home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Config.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  73.0 KB  |  3,234 lines

  1. /*
  2. **    Config.c
  3. **
  4. **    Configuration processing routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* Reset routine function pointer. */
  17.  
  18. typedef VOID (* RESET)(APTR,STRPTR);
  19.  
  20.     /* Local routines. */
  21.  
  22. STATIC BOOL    ReadSystemPrefs(STRPTR Name,ULONG ID,APTR Data,LONG Size,LONG Count);
  23.  
  24. STATIC VOID    ResetSerialConfig(struct SerialSettings *SerialConfig);
  25. STATIC VOID    ResetModem(struct ModemSettings *ModemConfig);
  26. STATIC VOID    ResetScreen(struct ScreenSettings *ScreenConfig);
  27. STATIC VOID    ResetTerminal(struct TerminalSettings *TerminalConfig);
  28. STATIC VOID    ResetEmulation(struct EmulationSettings *EmulationConfig);
  29. STATIC VOID    ResetClip(struct ClipSettings *ClipConfig);
  30. STATIC VOID    ResetCapture(struct CaptureSettings *CaptureConfig);
  31. STATIC VOID    ResetFile(struct FileSettings *FileConfig,STRPTR PathBuffer);
  32. STATIC VOID    ResetPath(struct PathSettings *PathConfig,STRPTR PathBuffer);
  33. STATIC VOID    ResetMisc(struct MiscSettings *MiscConfig);
  34. STATIC VOID    ResetCommand(struct CommandSettings *CommandConfig);
  35. STATIC VOID    ResetTransfer(struct TransferSettings *TransferConfig,STRPTR DefaultLib);
  36. STATIC VOID    ResetTranslationFile(STRPTR Arg,STRPTR PathBuffer);
  37. STATIC VOID    ResetMacroFile(STRPTR Arg,STRPTR PathBuffer);
  38. STATIC VOID    ResetCursorFile(STRPTR Arg,STRPTR PathBuffer);
  39. STATIC VOID    ResetFastMacroFile(STRPTR Arg,STRPTR PathBuffer);
  40. STATIC VOID    ResetSpeechFile(STRPTR Arg,STRPTR PathBuffer);
  41. STATIC VOID    ResetSoundFile(STRPTR Arg,STRPTR PathBuffer);
  42. STATIC VOID    ResetAreaCodeFile(STRPTR Arg,STRPTR PathBuffer);
  43. STATIC VOID    ResetPhonebookFile(STRPTR Arg,STRPTR PathBuffer);
  44. STATIC VOID    ResetHotkeyFile(STRPTR Arg,STRPTR PathBuffer);
  45. STATIC VOID    ResetTrapFile(STRPTR Arg,STRPTR PathBuffer);
  46.  
  47. STATIC BOOL    WriteConfigChunk(struct IFFHandle *Handle,struct Configuration *Config,LONG Type,APTR TempBuffer,STRPTR Password);
  48. STATIC BOOL    WriteConfigChunks(struct IFFHandle *Handle,struct Configuration *Config,APTR TempBuffer,STRPTR Password);
  49. STATIC LONG    IsConfigChunk(ULONG ID);
  50. STATIC BOOL    ReadConfigChunk(struct IFFHandle *Handle,struct Configuration *Config,LONG Type,LONG Len,STRPTR Password);
  51.  
  52. /*****************************************************************************/
  53.  
  54. STATIC BOOLEAN                FontPrefsRead        = FALSE,
  55.                             FontPrefsReadFailed    = FALSE;
  56. STATIC struct FontPrefs        FontPrefs[3];
  57.  
  58. /*****************************************************************************/
  59.  
  60. STATIC UWORD SizeTable[] =
  61. {
  62.     sizeof(struct SerialSettings),
  63.     sizeof(struct ModemSettings),
  64.     sizeof(struct CommandSettings),
  65.     sizeof(struct ScreenSettings),
  66.     sizeof(struct TerminalSettings),
  67.     sizeof(struct PathSettings),
  68.     sizeof(struct MiscSettings),
  69.     sizeof(struct ClipSettings),
  70.     sizeof(struct CaptureSettings),
  71.     sizeof(struct FileSettings),
  72.     sizeof(struct EmulationSettings),
  73.     sizeof(struct TransferSettings),
  74.     MAX_FILENAME_LENGTH,                // Translation file name
  75.     MAX_FILENAME_LENGTH,                // Macro file name
  76.     MAX_FILENAME_LENGTH,                // Cursor file name
  77.     MAX_FILENAME_LENGTH,                // Fast macro file name
  78.     MAX_FILENAME_LENGTH,                // Speech file name
  79.     MAX_FILENAME_LENGTH,                // Sound file name
  80.     MAX_FILENAME_LENGTH,                // Area code file name
  81.     MAX_FILENAME_LENGTH,                // Phonebook file name
  82.     MAX_FILENAME_LENGTH,                // Hotkey file name
  83.     MAX_FILENAME_LENGTH                    // Trap file name
  84. };
  85.  
  86. STATIC RESET ResetTable[] =
  87. {
  88.     (RESET)ResetSerialConfig,
  89.     (RESET)ResetModem,
  90.     (RESET)ResetCommand,
  91.     (RESET)ResetScreen,
  92.     (RESET)ResetTerminal,
  93.     ResetPath,
  94.     (RESET)ResetMisc,
  95.     (RESET)ResetClip,
  96.     (RESET)ResetCapture,
  97.     ResetFile,
  98.     (RESET)ResetEmulation,
  99.     ResetTransfer,
  100.     (RESET)ResetTranslationFile,
  101.     (RESET)ResetMacroFile,
  102.     (RESET)ResetCursorFile,
  103.     (RESET)ResetFastMacroFile,
  104.     (RESET)ResetSpeechFile,
  105.     (RESET)ResetSoundFile,
  106.     (RESET)ResetAreaCodeFile,
  107.     (RESET)ResetPhonebookFile,
  108.     (RESET)ResetHotkeyFile,
  109.     (RESET)ResetTrapFile
  110. };
  111.  
  112. STATIC ULONG TypeTable[] =
  113. {
  114.     ID_SERL,
  115.     ID_MODM,
  116.     ID_COMD,
  117.     ID_SCRN,
  118.     ID_TRML,
  119.     ID_PATH,
  120.     ID_MISC,
  121.     ID_CLIP,
  122.     ID_CPTR,
  123.     ID_FILE,
  124.     ID_EMLN,
  125.     ID_XFER,
  126.     ID_XLNM,
  127.     ID_MFNM,
  128.     ID_CRNM,
  129.     ID_FMNM,
  130.     ID_SPNM,
  131.     ID_SONM,
  132.     ID_ACNM,
  133.     ID_PBNM,
  134.     ID_HKNM,
  135.     ID_TRNM
  136. };
  137.  
  138. #define NUM_STOPS (sizeof(Stops) / (2 * sizeof(ULONG)))
  139.  
  140. STATIC LONG Stops[] =
  141. {
  142.     ID_TERM,ID_CAT,
  143.     ID_TERM,ID_VERS,
  144.     ID_TERM,ID_DIAL,
  145.     ID_TERM,ID_DAT2,
  146.     ID_TERM,ID_DATE,
  147.     ID_TERM,ID_PHON,
  148.     ID_TERM,ID_PSWD,
  149.  
  150.     ID_TERM,ID_SERL,
  151.     ID_TERM,ID_MODM,
  152.     ID_TERM,ID_COMD,
  153.     ID_TERM,ID_SCRN,
  154.     ID_TERM,ID_TRML,
  155.     ID_TERM,ID_PATH,
  156.     ID_TERM,ID_MISC,
  157.     ID_TERM,ID_CLIP,
  158.     ID_TERM,ID_CPTR,
  159.     ID_TERM,ID_FILE,
  160.     ID_TERM,ID_EMLN,
  161.     ID_TERM,ID_XFER,
  162.     ID_TERM,ID_WINF,
  163.     ID_TERM,ID_GRUP,
  164.     ID_TERM,ID_XLNM,
  165.     ID_TERM,ID_MFNM,
  166.     ID_TERM,ID_CRNM,
  167.     ID_TERM,ID_FMNM,
  168.     ID_TERM,ID_SPNM,
  169.     ID_TERM,ID_SONM,
  170.     ID_TERM,ID_ACNM,
  171.     ID_TERM,ID_PBNM,
  172.     ID_TERM,ID_HKNM,
  173.     ID_TERM,ID_TRNM
  174. };
  175.  
  176. /*****************************************************************************/
  177.  
  178. enum    {    CR_IGNORE,CR_ASCR,CR_ASCRLF };
  179. enum    {    LF_IGNORE,LF_ASLF,LF_ASLFCR };
  180.  
  181. /*****************************************************************************/
  182.  
  183. VOID
  184. StripGlobals(struct Configuration *Config)
  185. {
  186.     if(Config)
  187.     {
  188.         FreeVecPooled(Config->SpeechFileName);
  189.         FreeVecPooled(Config->SoundFileName);
  190.         FreeVecPooled(Config->AreaCodeFileName);
  191.         FreeVecPooled(Config->PhonebookFileName);
  192.         FreeVecPooled(Config->HotkeyFileName);
  193.         FreeVecPooled(Config->TrapFileName);
  194.  
  195.         Config->SpeechFileName        = NULL;
  196.         Config->SoundFileName        = NULL;
  197.         Config->AreaCodeFileName    = NULL;
  198.         Config->PhonebookFileName    = NULL;
  199.         Config->HotkeyFileName        = NULL;
  200.         Config->TrapFileName        = NULL;
  201.     }
  202. }
  203.  
  204. VOID
  205. FinalFix(struct Configuration *Config,BOOL IsPhonebook,LONG Version,LONG Revision)
  206. {
  207.     if(Config)
  208.     {
  209.         if(Version < 4 || (Version == 4 && Revision < 3))
  210.         {
  211.             if(Config->TransferConfig && Config->MiscConfig)
  212.             {
  213.                 Config->TransferConfig->OverridePath    = Config->MiscConfig->OverridePath;
  214.                 Config->TransferConfig->SetArchivedBit    = Config->MiscConfig->SetArchivedBit;
  215.                 Config->TransferConfig->IdentifyFiles    = Config->MiscConfig->IdentifyFiles;
  216.                 Config->TransferConfig->TransferIcons    = Config->MiscConfig->TransferIcons;
  217.                 Config->TransferConfig->PerfMeter        = Config->MiscConfig->PerfMeter;
  218.                 Config->TransferConfig->HideUploadIcon    = Config->MiscConfig->HideUploadIcon;
  219.             }
  220.         }
  221.  
  222.         if(Version < 4 || (Version == 4 && Revision < 4))
  223.         {
  224.             if(Config->TerminalConfig && Config->MiscConfig)
  225.                 Config->MiscConfig->AlertMode = Config->TerminalConfig->AlertMode;
  226.         }
  227.     }
  228. }
  229.  
  230. VOID
  231. FixOldConfig(struct Configuration *Config,UBYTE ConfigChunkType,BOOL IsPhonebook,LONG Version,LONG Revision)
  232. {
  233.     if((Version == 3 && Revision < 6) || Version < 3)
  234.     {
  235.         if(ConfigChunkType == PREF_CLIP)
  236.             Config->ClipConfig->ConvertLF = TRUE;
  237.  
  238.         if(ConfigChunkType == PREF_SERIAL)
  239.             Config->SerialConfig->UseOwnDevUnit = TRUE;
  240.  
  241.         if(ConfigChunkType == PREF_MISC)
  242.             Config->MiscConfig->ProtectiveMode = TRUE;
  243.  
  244.         if(ConfigChunkType == PREF_SCREEN)
  245.         {
  246.             Config->ScreenConfig->UsePens        = TRUE;
  247.             Config->ScreenConfig->Depth            = 0;
  248.             Config->ScreenConfig->PenColourMode    = 42;    // Avoid trouble
  249.         }
  250.  
  251.         if(ConfigChunkType == PREF_TRANSFER)
  252.         {
  253.             LONG i;
  254.  
  255.             Config->TransferConfig->MangleFileNames = FALSE;
  256.  
  257.             if(Config->TransferConfig->ASCIIUploadLibrary[0])
  258.                 Config->TransferConfig->ASCIIUploadType = XFER_XPR;
  259.  
  260.             if(Config->TransferConfig->ASCIIDownloadLibrary[0])
  261.                 Config->TransferConfig->ASCIIDownloadType = XFER_XPR;
  262.  
  263.             if(Config->TransferConfig->TextUploadLibrary[0])
  264.                 Config->TransferConfig->TextUploadType = XFER_XPR;
  265.  
  266.             if(Config->TransferConfig->TextDownloadLibrary[0])
  267.                 Config->TransferConfig->TextDownloadType = XFER_XPR;
  268.  
  269.             if(Config->TransferConfig->BinaryUploadLibrary[0])
  270.                 Config->TransferConfig->BinaryUploadType = XFER_XPR;
  271.  
  272.             if(Config->TransferConfig->BinaryDownloadLibrary[0])
  273.                 Config->TransferConfig->BinaryDownloadType = XFER_XPR;
  274.  
  275.             for(i = 0 ; i < strlen(Config->TransferConfig->DefaultLibrary) - 6 ; i++)
  276.             {
  277.                 if(!Strnicmp(&Config->TransferConfig->DefaultLibrary[i],"zmodem",6))
  278.                 {
  279.                     strcpy(Config->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  280.  
  281.                     Config->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(Config->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  282.  
  283.                     break;
  284.                 }
  285.             }
  286.         }
  287.  
  288.         if(ConfigChunkType == PREF_MODEM)
  289.             Config->ModemConfig->AbortHangsUp = FALSE;
  290.  
  291.         if(ConfigChunkType == PREF_COMMAND && IsPhonebook)
  292.         {
  293.             strcpy(Config->CommandConfig->LoginMacro,Config->CommandConfig->StartupMacro);
  294.  
  295.             memset(Config->CommandConfig->StartupMacro,0,sizeof(Config->CommandConfig->StartupMacro));
  296.         }
  297.  
  298.         if(ConfigChunkType == PREF_CAPTURE)
  299.             Config->CaptureConfig->SearchHistory = 10;
  300.  
  301.         if(ConfigChunkType == PREF_EMULATION)
  302.         {
  303.             if(Config->EmulationConfig->DestructiveBackspace < 0 || Config->EmulationConfig->DestructiveBackspace > 2)
  304.                 Config->EmulationConfig->DestructiveBackspace = 1;
  305.         }
  306.     }
  307.  
  308.     if((Version == 4 && Revision < 1) || Version < 4)
  309.     {
  310.         if(ConfigChunkType == PREF_CLIP)
  311.             Config->ClipConfig->ConvertLF = TRUE;
  312.  
  313.         if(ConfigChunkType == PREF_SERIAL)
  314.         {
  315.             Config->SerialConfig->xONxOFF        = FALSE;
  316.             Config->SerialConfig->PassThrough    = TRUE;
  317.         }
  318.  
  319.         if(ConfigChunkType == PREF_MISC)
  320.             Config->MiscConfig->ProtectiveMode = TRUE;
  321.  
  322.         if(ConfigChunkType == PREF_MODEM)
  323.         {
  324.             Config->ModemConfig->RedialDelay    = (Config->ModemConfig->RedialDelay / 6) * 60 + (Config->ModemConfig->RedialDelay % 6) * 10;
  325.             Config->ModemConfig->TimeToConnect    = (Config->ModemConfig->TimeToConnect / 6) * 60 + (Config->ModemConfig->TimeToConnect % 6) * 10;
  326.             Config->ModemConfig->VerboseDialing    = FALSE;
  327.         }
  328.  
  329.         if(ConfigChunkType == PREF_TERMINAL)
  330.         {
  331.             switch(Config->TerminalConfig->SendCR)
  332.             {
  333.                 case CR_IGNORE:
  334.  
  335.                     Config->TerminalConfig->SendCR = EOL_IGNORE;
  336.                     break;
  337.  
  338.                 case CR_ASCR:
  339.  
  340.                     Config->TerminalConfig->SendCR = EOL_CR;
  341.                     break;
  342.  
  343.                 case CR_ASCRLF:
  344.  
  345.                     Config->TerminalConfig->SendCR = EOL_CRLF;
  346.                     break;
  347.             }
  348.  
  349.             switch(Config->TerminalConfig->ReceiveCR)
  350.             {
  351.                 case CR_IGNORE:
  352.  
  353.                     Config->TerminalConfig->ReceiveCR = EOL_IGNORE;
  354.                     break;
  355.  
  356.                 case CR_ASCR:
  357.  
  358.                     Config->TerminalConfig->ReceiveCR = EOL_CR;
  359.                     break;
  360.  
  361.                 case CR_ASCRLF:
  362.  
  363.                     Config->TerminalConfig->ReceiveCR = EOL_CRLF;
  364.                     break;
  365.             }
  366.  
  367.             switch(Config->TerminalConfig->SendLF)
  368.             {
  369.                 case LF_IGNORE:
  370.  
  371.                     Config->TerminalConfig->SendLF = EOL_IGNORE;
  372.                     break;
  373.  
  374.                 case LF_ASLF:
  375.  
  376.                     Config->TerminalConfig->SendLF = EOL_LF;
  377.                     break;
  378.  
  379.                 case LF_ASLFCR:
  380.  
  381.                     Config->TerminalConfig->SendLF = EOL_LFCR;
  382.                     break;
  383.             }
  384.  
  385.             switch(Config->TerminalConfig->ReceiveLF)
  386.             {
  387.                 case LF_IGNORE:
  388.  
  389.                     Config->TerminalConfig->ReceiveLF = EOL_IGNORE;
  390.                     break;
  391.  
  392.                 case LF_ASLF:
  393.  
  394.                     Config->TerminalConfig->ReceiveLF = EOL_LF;
  395.                     break;
  396.  
  397.                 case LF_ASLFCR:
  398.  
  399.                     Config->TerminalConfig->ReceiveLF = EOL_LFCR;
  400.                     break;
  401.             }
  402.         }
  403.  
  404.         if(ConfigChunkType == PREF_TRANSFER)
  405.         {
  406.             LONG i;
  407.  
  408.             if(Config->TransferConfig->ASCIIUploadLibrary[0])
  409.                 Config->TransferConfig->ASCIIUploadType = XFER_XPR;
  410.  
  411.             if(Config->TransferConfig->ASCIIDownloadLibrary[0])
  412.                 Config->TransferConfig->ASCIIDownloadType = XFER_XPR;
  413.  
  414.             if(Config->TransferConfig->TextUploadLibrary[0])
  415.                 Config->TransferConfig->TextUploadType = XFER_XPR;
  416.  
  417.             if(Config->TransferConfig->TextDownloadLibrary[0])
  418.                 Config->TransferConfig->TextDownloadType = XFER_XPR;
  419.  
  420.             if(Config->TransferConfig->BinaryUploadLibrary[0])
  421.                 Config->TransferConfig->BinaryUploadType = XFER_XPR;
  422.  
  423.             if(Config->TransferConfig->BinaryDownloadLibrary[0])
  424.                 Config->TransferConfig->BinaryDownloadType = XFER_XPR;
  425.  
  426.             for(i = 0 ; i < strlen(Config->TransferConfig->DefaultLibrary) - 6 ; i++)
  427.             {
  428.                 if(!Strnicmp(&Config->TransferConfig->DefaultLibrary[i],"zmodem",6))
  429.                 {
  430.                     strcpy(Config->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  431.  
  432.                     Config->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(Config->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  433.  
  434.                     break;
  435.                 }
  436.             }
  437.  
  438.             switch(Config->TransferConfig->SendCR)
  439.             {
  440.                 case CR_IGNORE:
  441.  
  442.                     Config->TransferConfig->SendCR = EOL_IGNORE;
  443.                     break;
  444.  
  445.                 case CR_ASCR:
  446.  
  447.                     Config->TransferConfig->SendCR = EOL_CR;
  448.                     break;
  449.  
  450.                 case CR_ASCRLF:
  451.  
  452.                     Config->TransferConfig->SendCR = EOL_CRLF;
  453.                     break;
  454.             }
  455.  
  456.             switch(Config->TransferConfig->ReceiveCR)
  457.             {
  458.                 case CR_IGNORE:
  459.  
  460.                     Config->TransferConfig->ReceiveCR = EOL_IGNORE;
  461.                     break;
  462.  
  463.                 case CR_ASCR:
  464.  
  465.                     Config->TransferConfig->ReceiveCR = EOL_CR;
  466.                     break;
  467.  
  468.                 case CR_ASCRLF:
  469.  
  470.                     Config->TransferConfig->ReceiveCR = EOL_CRLF;
  471.                     break;
  472.             }
  473.  
  474.             switch(Config->TransferConfig->SendLF)
  475.             {
  476.                 case LF_IGNORE:
  477.  
  478.                     Config->TransferConfig->SendLF = EOL_IGNORE;
  479.                     break;
  480.  
  481.                 case LF_ASLF:
  482.  
  483.                     Config->TransferConfig->SendLF = EOL_LF;
  484.                     break;
  485.  
  486.                 case LF_ASLFCR:
  487.  
  488.                     Config->TransferConfig->SendLF = EOL_LFCR;
  489.                     break;
  490.             }
  491.  
  492.             switch(Config->TransferConfig->ReceiveLF)
  493.             {
  494.                 case LF_IGNORE:
  495.  
  496.                     Config->TransferConfig->ReceiveLF = EOL_IGNORE;
  497.                     break;
  498.  
  499.                 case LF_ASLF:
  500.  
  501.                     Config->TransferConfig->ReceiveLF = EOL_LF;
  502.                     break;
  503.  
  504.                 case LF_ASLFCR:
  505.  
  506.                     Config->TransferConfig->ReceiveLF = EOL_LFCR;
  507.                     break;
  508.             }
  509.         }
  510.     }
  511.  
  512.     if(Version == 4 && Revision < 3)
  513.     {
  514.         if(ConfigChunkType == PREF_CLIP)
  515.             Config->ClipConfig->ConvertLF = TRUE;
  516.  
  517.         if(ConfigChunkType == PREF_SERIAL)
  518.         {
  519.             Config->SerialConfig->xONxOFF        = FALSE;
  520.             Config->SerialConfig->PassThrough    = TRUE;
  521.         }
  522.  
  523.         if(ConfigChunkType == PREF_MISC)
  524.             Config->MiscConfig->ProtectiveMode = TRUE;
  525.  
  526.         if(ConfigChunkType == PREF_TRANSFER)
  527.         {
  528.             LONG i;
  529.  
  530.             for(i = 0 ; i < strlen(Config->TransferConfig->DefaultLibrary) - 6 ; i++)
  531.             {
  532.                 if(!Strnicmp(&Config->TransferConfig->DefaultLibrary[i],"zmodem",6))
  533.                 {
  534.                     strcpy(Config->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  535.  
  536.                     Config->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(Config->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  537.  
  538.                     break;
  539.                 }
  540.             }
  541.  
  542.             if(Config->TransferConfig->ASCIIUploadLibrary[0])
  543.                 Config->TransferConfig->ASCIIUploadType = XFER_XPR;
  544.  
  545.             if(Config->TransferConfig->ASCIIDownloadLibrary[0])
  546.                 Config->TransferConfig->ASCIIDownloadType = XFER_XPR;
  547.  
  548.             if(Config->TransferConfig->InternalASCIIUpload)
  549.                 Config->TransferConfig->ASCIIUploadType = XFER_INTERNAL;
  550.  
  551.             if(Config->TransferConfig->InternalASCIIDownload)
  552.                 Config->TransferConfig->ASCIIDownloadType = XFER_INTERNAL;
  553.  
  554.             if(Config->TransferConfig->TextUploadLibrary[0])
  555.                 Config->TransferConfig->TextUploadType = XFER_XPR;
  556.  
  557.             if(Config->TransferConfig->TextDownloadLibrary[0])
  558.                 Config->TransferConfig->TextDownloadType = XFER_XPR;
  559.  
  560.             if(Config->TransferConfig->BinaryUploadLibrary[0])
  561.                 Config->TransferConfig->BinaryUploadType = XFER_XPR;
  562.  
  563.             if(Config->TransferConfig->BinaryDownloadLibrary[0])
  564.                 Config->TransferConfig->BinaryDownloadType = XFER_XPR;
  565.         }
  566.     }
  567. }
  568.  
  569. VOID
  570. FixScreenPens(struct ScreenSettings *ScreenConfig)
  571. {
  572.     LONG i,Count;
  573.  
  574.     for(Count = 0, i = DETAILPEN ; i <= BARTRIMPEN ; i++)
  575.     {
  576.         if(ScreenConfig->PenArray[i])
  577.             Count++;
  578.     }
  579.  
  580.     if(!Count)
  581.         ScreenConfig->UsePens = TRUE;
  582. }
  583.  
  584. /*****************************************************************************/
  585.  
  586.     /* ReadSystemPrefs():
  587.      *
  588.      *    Reads the system preferences settings.
  589.      */
  590.  
  591. STATIC BOOL
  592. ReadSystemPrefs(STRPTR Name,ULONG ID,APTR Data,LONG Size,LONG Count)
  593. {
  594.     struct IFFHandle    *Handle;
  595.     BOOL                 Success = FALSE;
  596.     LONG                 Error;
  597.  
  598.         /* Allocate an IFF handle. */
  599.  
  600.     if(Handle = AllocIFF())
  601.     {
  602.             /* Open the preferences settings file. */
  603.  
  604.         if(Handle->iff_Stream = Open(Name,MODE_OLDFILE))
  605.         {
  606.                 /* Make it known as a DOS file handle. */
  607.  
  608.             InitIFFasDOS(Handle);
  609.  
  610.                 /* Open the file for reading. */
  611.  
  612.             if(!(Error = OpenIFF(Handle,IFFF_READ)))
  613.             {
  614.                     /* Stop at the `body' chunk. */
  615.  
  616.                 if(!(Error = StopChunk(Handle,ID_PREF,ID)))
  617.                 {
  618.                         /* Look for it... */
  619.  
  620.                     while(!ParseIFF(Handle,IFFPARSE_SCAN))
  621.                     {
  622.                             /* Read the data. */
  623.  
  624.                         if(ReadChunkBytes(Handle,Data,Size) == Size)
  625.                         {
  626.                             Success = TRUE;
  627.  
  628.                             if(Count)
  629.                             {
  630.                                 Count--;
  631.  
  632.                                 Data = (APTR)((ULONG)Data + Size);
  633.                             }
  634.                             else
  635.                                 break;
  636.                         }
  637.                         else
  638.                         {
  639.                             Error = IoErr();
  640.  
  641.                             Success = FALSE;
  642.  
  643.                             break;
  644.                         }
  645.                     }
  646.                 }
  647.  
  648.                     /* Close the handle. */
  649.  
  650.                 CloseIFF(Handle);
  651.             }
  652.  
  653.                 /* Release the handle. */
  654.  
  655.             Close(Handle->iff_Stream);
  656.         }
  657.         else
  658.             Error = IoErr();
  659.  
  660.             /* Clean up. */
  661.  
  662.         FreeIFF(Handle);
  663.     }
  664.     else
  665.         Error = ERR_NO_MEM;
  666.  
  667.     if(Error)
  668.         SetIoErr(Error);
  669.  
  670.         /* Return sucess/failure. */
  671.  
  672.     return(Success);
  673. }
  674.  
  675. /*****************************************************************************/
  676.  
  677. STATIC VOID
  678. ResetSerialConfig(struct SerialSettings *SerialConfig)
  679. {
  680.     STATIC BOOLEAN                SerialPrefsRead            = FALSE,
  681.                                 SerialPrefsReadFailed    = FALSE;
  682.     STATIC struct SerialPrefs    SerialPrefs;
  683.  
  684.         /* The program will only try to read the preferences
  685.          * settings once; if the first access failed, no
  686.          * other accesses will be made.
  687.          */
  688.  
  689.     if(!SerialPrefsRead && !SerialPrefsReadFailed)
  690.         SerialPrefsReadFailed = ReadSystemPrefs("ENV:sys/serial.prefs",ID_SERL,&SerialPrefs,sizeof(SerialPrefs),1) ^ TRUE;
  691.  
  692.         /* Did we succeed in reading the file? */
  693.  
  694.     if(!SerialPrefsRead)
  695.     {
  696.         SerialConfig->BaudRate                = 19200;
  697.         SerialConfig->BitsPerChar            = 8;
  698.         SerialConfig->Parity                = PARITY_NONE;
  699.         SerialConfig->StopBits                = 1;
  700.         SerialConfig->HandshakingProtocol    = HANDSHAKING_RTSCTS_DSR;
  701.         SerialConfig->SerialBufferSize        = 32768;
  702.     }
  703.     else
  704.     {
  705.             /* Fill in the common data. */
  706.  
  707.         SerialConfig->BaudRate            = SerialPrefs.sp_BaudRate;
  708.         SerialConfig->SerialBufferSize    = SerialPrefs.sp_InputBuffer;
  709.         SerialConfig->BitsPerChar        = SerialPrefs.sp_BitsPerChar;
  710.         SerialConfig->StopBits            = SerialPrefs.sp_StopBits;
  711.  
  712.             /* Convert the handshaking mode. */
  713.  
  714.         switch(SerialPrefs.sp_InputHandshake)
  715.         {
  716.             case HSHAKE_NONE:
  717.  
  718.                 SerialConfig->HandshakingProtocol = HANDSHAKING_NONE;
  719.  
  720.                 break;
  721.  
  722.             case HSHAKE_RTS:
  723.  
  724.                 SerialConfig->HandshakingProtocol = HANDSHAKING_RTSCTS_DSR;
  725.  
  726.                 break;
  727.  
  728.             default:
  729.  
  730.                 SerialConfig->HandshakingProtocol = HANDSHAKING_NONE;
  731.  
  732.                 break;
  733.         }
  734.  
  735.             /* Convert the parity settings. */
  736.  
  737.         if(SerialPrefs.sp_Parity <= PARITY_SPACE)
  738.             SerialConfig->Parity = SerialPrefs.sp_Parity;
  739.         else
  740.             SerialConfig->Parity = PARITY_NONE;
  741.  
  742.         SerialPrefsRead = TRUE;
  743.     }
  744.  
  745.     strcpy(SerialConfig->SerialDevice,SERIALNAME);
  746.  
  747.     SerialConfig->Duplex                = DUPLEX_FULL;
  748.     SerialConfig->BreakLength            = 250000;
  749.     SerialConfig->UnitNumber            = 0;
  750.     SerialConfig->PassThrough            = TRUE;
  751.  
  752.     SerialConfig->Quantum                = 256;
  753.  
  754.     SerialConfig->NetID                    = 0002;
  755.  
  756.     SerialConfig->SatisfyODURequests    = ODU_RELEASE;
  757. }
  758.  
  759. STATIC VOID
  760. ResetModem(struct ModemSettings *ModemConfig)
  761. {
  762.     strcpy(ModemConfig->ModemInit,            "ATX3E1V1Q0\\r");
  763.     strcpy(ModemConfig->ModemExit,            "");
  764.     strcpy(ModemConfig->ModemHangup,        "~~~~+++~~~~ATH0\\r");
  765.     strcpy(ModemConfig->DialPrefix,            "ATD\\w");
  766.     strcpy(ModemConfig->DialSuffix,            "\\r");
  767.  
  768.     strcpy(ModemConfig->NoCarrier,            "NO CARRIER");
  769.     strcpy(ModemConfig->NoDialTone,            "NO DIALTONE");
  770.     strcpy(ModemConfig->Connect,            "CONNECT");
  771.     strcpy(ModemConfig->Voice,                "VOICE");
  772.     strcpy(ModemConfig->Ring,                "RING");
  773.     strcpy(ModemConfig->Busy,                "BUSY");
  774.     strcpy(ModemConfig->Ok,                    "OK");
  775.     strcpy(ModemConfig->Error,                "ERROR");
  776.  
  777.     ModemConfig->RedialDelay                = 20;
  778.     ModemConfig->DialRetries                = 10;
  779.     ModemConfig->DialTimeout                = 60;
  780.  
  781.     ModemConfig->NoCarrierIsBusy            = TRUE;
  782.  
  783.     ModemConfig->DialMode                    = DIALMODE_PULSE;
  784.  
  785.     strcpy(ModemConfig->PBX_Prefix,            "0,,,");
  786. }
  787.  
  788. STATIC VOID
  789. ResetScreen(struct ScreenSettings *ScreenConfig)
  790. {
  791.     ULONG             DisplayID;
  792.     struct Screen    *PubScreen;
  793.  
  794.     if(!FontPrefsRead && !FontPrefsReadFailed)
  795.         FontPrefsReadFailed = ReadSystemPrefs("ENV:sys/font.prefs",ID_FONT,FontPrefs,sizeof(struct FontPrefs),3) ^ TRUE;
  796.  
  797.     DisplayID = INVALID_ID;
  798.  
  799.     strcpy(ScreenConfig->FontName,"topaz.font");
  800.     ScreenConfig->FontHeight = 8;
  801.  
  802.     if(!FontPrefsReadFailed)
  803.     {
  804.         LONG i;
  805.  
  806.         for(i = 0 ; i < 3 ; i++)
  807.         {
  808.             if(FontPrefs[i].fp_Type == FP_SCREENFONT)
  809.             {
  810.                 strcpy(ScreenConfig->FontName,FontPrefs[i].fp_Name);
  811.                 ScreenConfig->FontHeight = FontPrefs[i].fp_TextAttr.ta_YSize;
  812.  
  813.                 break;
  814.             }
  815.         }
  816.     }
  817.  
  818.     if(DisplayID == INVALID_ID)
  819.     {
  820.         if(PubScreen = LockPubScreen(NULL))
  821.         {
  822.             DisplayID = GetVPModeID(&PubScreen->ViewPort);
  823.  
  824.             UnlockPubScreen(NULL,PubScreen);
  825.         }
  826.         else
  827.             DisplayID = DEFAULT_MONITOR_ID | HIRESLACE_KEY;
  828.     }
  829.  
  830.     ScreenConfig->DisplayMode        = DisplayID;
  831.     ScreenConfig->ColourMode        = COLOUR_AMIGA;
  832.     ScreenConfig->MakeScreenPublic    = TRUE;
  833.     ScreenConfig->TitleBar            = TRUE;
  834.     ScreenConfig->StatusLine        = STATUSLINE_STANDARD;
  835.     ScreenConfig->Blinking            = TRUE;
  836.     ScreenConfig->FasterLayout        = TRUE;
  837.  
  838.     ScreenConfig->TimeMode            = ONLINETIME_BOTH;
  839.     ScreenConfig->UsePens            = TRUE;
  840.     ScreenConfig->PenColourMode        = COLOUR_AMIGA;
  841.  
  842.     ScreenConfig->OverscanType        = OSCAN_TEXT;
  843. }
  844.  
  845. STATIC VOID
  846. ResetTerminal(struct TerminalSettings *TerminalConfig)
  847. {
  848.     if(!FontPrefsRead && !FontPrefsReadFailed)
  849.         FontPrefsReadFailed = ReadSystemPrefs("ENV:sys/font.prefs",ID_FONT,FontPrefs,sizeof(struct FontPrefs),3) ^ TRUE;
  850.  
  851.     strcpy(TerminalConfig->TextFontName,"topaz.font");
  852.     TerminalConfig->TextFontHeight = 8;
  853.  
  854.     strcpy(TerminalConfig->IBMFontName,"IBM.font");
  855.     TerminalConfig->IBMFontHeight = 8;
  856.  
  857.     if(!FontPrefsReadFailed)
  858.     {
  859.         LONG i;
  860.  
  861.         for(i = 0 ; i < 3 ; i++)
  862.         {
  863.             if(FontPrefs[i].fp_Type == FP_SYSFONT)
  864.             {
  865.                 strcpy(TerminalConfig->TextFontName,FontPrefs[i].fp_Name);
  866.                 TerminalConfig->TextFontHeight = FontPrefs[i].fp_TextAttr.ta_YSize;
  867.  
  868.                 if(TerminalConfig->TextFontHeight == 8 || TerminalConfig->TextFontHeight == 11)
  869.                     TerminalConfig->IBMFontHeight = TerminalConfig->TextFontHeight;
  870.  
  871.                 break;
  872.             }
  873.         }
  874.     }
  875.  
  876.     TerminalConfig->BellMode                = BELL_AUDIBLE;
  877.     TerminalConfig->AlertMode                = ALERT_BEEP_SCREEN;
  878.     TerminalConfig->EmulationMode            = EMULATION_ANSIVT100;
  879.     TerminalConfig->FontMode                = FONT_STANDARD;
  880.  
  881.     TerminalConfig->SendCR                    = EOL_CR;
  882.     TerminalConfig->SendLF                    = EOL_LF;
  883.     TerminalConfig->ReceiveCR                = EOL_CR;
  884.     TerminalConfig->ReceiveLF                = EOL_LF;
  885. }
  886.  
  887. STATIC VOID
  888. ResetEmulation(struct EmulationSettings *EmulationConfig)
  889. {
  890.     LONG i;
  891.  
  892.     EmulationConfig->CursorMode                = KEYMODE_STANDARD;
  893.     EmulationConfig->NumericMode            = KEYMODE_STANDARD;
  894.  
  895.     EmulationConfig->LineWrap                = TRUE;
  896.  
  897.     EmulationConfig->FontScale                = SCALE_NORMAL;
  898.     EmulationConfig->ScrollMode                = SCROLL_JUMP;
  899.     EmulationConfig->PrinterEnabled            = TRUE;
  900.     EmulationConfig->MaxJump                = 1;
  901.  
  902.     EmulationConfig->UseStandardPens        = TRUE;
  903.  
  904.     for(i = TEXTATTR_UNDERLINE ; i <= TEXTATTR_INVERSE ; i++)
  905.         EmulationConfig->Attributes[i] = i;
  906.  
  907.     for(i = 0 ; i < 16 ; i++)
  908.         EmulationConfig->Pens[i] = i;
  909.  
  910.     EmulationConfig->TerminalType = TERMINAL_VT200;
  911. }
  912.  
  913. STATIC VOID
  914. ResetClip(struct ClipSettings *ClipConfig)
  915. {
  916.     strcpy(ClipConfig->InsertSuffix,"\\r");
  917.  
  918.     ClipConfig->PacingMode        = PACE_DIRECT;
  919.     ClipConfig->ConvertLF        = TRUE;
  920. }
  921.  
  922. STATIC VOID
  923. ResetCapture(struct CaptureSettings *CaptureConfig)
  924. {
  925.     CaptureConfig->BufferEnabled        = TRUE;
  926.  
  927.     CaptureConfig->CaptureFilterMode    = FILTER_BOTH;
  928.  
  929.     CaptureConfig->AutoCaptureDate        = AUTOCAPTURE_DATE_NAME;
  930.     CaptureConfig->SearchHistory        = 10;
  931.  
  932.     CaptureConfig->OpenBufferWindow        = BUFFER_END;
  933.     CaptureConfig->OpenBufferScreen        = BUFFER_TOP;
  934.     CaptureConfig->BufferScreenPosition    = SCREEN_CENTRE;
  935.     CaptureConfig->BufferWidth            = 80;
  936.  
  937.     CaptureConfig->BufferScreenMode        = INVALID_ID;
  938.  
  939.     CaptureConfig->BufferMode            = BUFFERMODE_FLOW;
  940. }
  941.  
  942. STATIC VOID
  943. ResetTranslationFile(STRPTR Here,STRPTR PathBuffer)
  944. {
  945.     if(!PathBuffer)
  946.         PathBuffer = "TERM:config";
  947.  
  948.     if(!LastTranslation[0])
  949.     {
  950.         strcpy(LastTranslation,PathBuffer);
  951.  
  952.         AddPart(LastTranslation,"translation.prefs",MAX_FILENAME_LENGTH);
  953.     }
  954.  
  955.     strcpy(Here,LastTranslation);
  956. }
  957.  
  958. STATIC VOID
  959. ResetMacroFile(STRPTR Here,STRPTR PathBuffer)
  960. {
  961.     if(!PathBuffer)
  962.         PathBuffer = "TERM:config";
  963.  
  964.     if(!LastMacros[0])
  965.     {
  966.         strcpy(LastMacros,PathBuffer);
  967.  
  968.         AddPart(LastMacros,"functionkeys.prefs",MAX_FILENAME_LENGTH);
  969.     }
  970.  
  971.     strcpy(Here,LastMacros);
  972. }
  973.  
  974. STATIC VOID
  975. ResetCursorFile(STRPTR Here,STRPTR PathBuffer)
  976. {
  977.     if(!PathBuffer)
  978.         PathBuffer = "TERM:config";
  979.  
  980.     if(!LastCursorKeys[0])
  981.     {
  982.         strcpy(LastCursorKeys,PathBuffer);
  983.  
  984.         AddPart(LastCursorKeys,"cursorkeys.prefs",MAX_FILENAME_LENGTH);
  985.     }
  986.  
  987.     strcpy(Here,LastCursorKeys);
  988. }
  989.  
  990. STATIC VOID
  991. ResetFastMacroFile(STRPTR Here,STRPTR PathBuffer)
  992. {
  993.     if(!PathBuffer)
  994.         PathBuffer = "TERM:config";
  995.  
  996.     if(!LastFastMacros[0])
  997.     {
  998.         strcpy(LastFastMacros,PathBuffer);
  999.  
  1000.         AddPart(LastFastMacros,"fastmacros.prefs",MAX_FILENAME_LENGTH);
  1001.     }
  1002.  
  1003.     strcpy(Here,LastFastMacros);
  1004. }
  1005.  
  1006. STATIC VOID
  1007. ResetSpeechFile(STRPTR Here,STRPTR PathBuffer)
  1008. {
  1009.     if(!PathBuffer)
  1010.         PathBuffer = "TERM:config";
  1011.  
  1012.     if(!LastSpeech[0])
  1013.     {
  1014.         strcpy(LastSpeech,PathBuffer);
  1015.  
  1016.         AddPart(LastSpeech,"speech.prefs",MAX_FILENAME_LENGTH);
  1017.     }
  1018.  
  1019.     strcpy(Here,LastSpeech);
  1020. }
  1021.  
  1022. STATIC VOID
  1023. ResetSoundFile(STRPTR Here,STRPTR PathBuffer)
  1024. {
  1025.     if(!PathBuffer)
  1026.         PathBuffer = "TERM:config";
  1027.  
  1028.     if(!LastSound[0])
  1029.     {
  1030.         strcpy(LastSound,PathBuffer);
  1031.  
  1032.         AddPart(LastSound,"sound.prefs",MAX_FILENAME_LENGTH);
  1033.     }
  1034.  
  1035.     strcpy(Here,LastSound);
  1036. }
  1037.  
  1038. STATIC VOID
  1039. ResetAreaCodeFile(STRPTR Here,STRPTR PathBuffer)
  1040. {
  1041.     if(!PathBuffer)
  1042.         PathBuffer = "TERM:config";
  1043.  
  1044.     if(!LastPattern[0])
  1045.     {
  1046.         strcpy(LastPattern,PathBuffer);
  1047.  
  1048.         AddPart(LastPattern,"rates.prefs",MAX_FILENAME_LENGTH);
  1049.     }
  1050.  
  1051.     strcpy(Here,LastPattern);
  1052. }
  1053.  
  1054. STATIC VOID
  1055. ResetPhonebookFile(STRPTR Here,STRPTR PathBuffer)
  1056. {
  1057.     if(!PathBuffer)
  1058.         PathBuffer = "TERM:config";
  1059.  
  1060.     if(!LastPhone[0])
  1061.     {
  1062.         strcpy(LastPhone,PathBuffer);
  1063.  
  1064.         AddPart(LastPhone,"phonebook.prefs",MAX_FILENAME_LENGTH);
  1065.     }
  1066.  
  1067.     strcpy(Here,LastPhone);
  1068. }
  1069.  
  1070. STATIC VOID
  1071. ResetHotkeyFile(STRPTR Here,STRPTR PathBuffer)
  1072. {
  1073.     if(!PathBuffer)
  1074.         PathBuffer = "TERM:config";
  1075.  
  1076.     if(!LastKeys[0])
  1077.     {
  1078.         strcpy(LastKeys,PathBuffer);
  1079.  
  1080.         AddPart(LastKeys,"hotkeys.prefs",MAX_FILENAME_LENGTH);
  1081.     }
  1082.  
  1083.     strcpy(Here,LastKeys);
  1084. }
  1085.  
  1086. STATIC VOID
  1087. ResetTrapFile(STRPTR Here,STRPTR PathBuffer)
  1088. {
  1089.     if(!PathBuffer)
  1090.         PathBuffer = "TERM:config";
  1091.  
  1092.     if(!LastTraps[0])
  1093.     {
  1094.         strcpy(LastTraps,PathBuffer);
  1095.  
  1096.         AddPart(LastTraps,"trap.prefs",MAX_FILENAME_LENGTH);
  1097.     }
  1098.  
  1099.     strcpy(Here,LastTraps);
  1100. }
  1101.  
  1102. STATIC VOID
  1103. ResetFile(struct FileSettings *FileConfig,STRPTR PathBuffer)
  1104. {
  1105.     if(!PathBuffer)
  1106.         PathBuffer = "TERM:config";
  1107.  
  1108.     strcpy(FileConfig->ProtocolFileName,"xprzmodem.library");
  1109.  
  1110.     if(!LastTranslation[0])
  1111.     {
  1112.         strcpy(LastTranslation,PathBuffer);
  1113.  
  1114.         AddPart(LastTranslation,"translation.prefs",MAX_FILENAME_LENGTH);
  1115.     }
  1116.  
  1117.     strcpy(FileConfig->TranslationFileName,LastTranslation);
  1118.  
  1119.     if(!LastMacros[0])
  1120.     {
  1121.         strcpy(LastMacros,PathBuffer);
  1122.  
  1123.         AddPart(LastMacros,"functionkeys.prefs",MAX_FILENAME_LENGTH);
  1124.     }
  1125.  
  1126.     strcpy(FileConfig->MacroFileName,LastMacros);
  1127.  
  1128.     if(!LastFastMacros[0])
  1129.     {
  1130.         strcpy(LastFastMacros,PathBuffer);
  1131.  
  1132.         AddPart(LastFastMacros,"fastmacros.prefs",MAX_FILENAME_LENGTH);
  1133.     }
  1134.  
  1135.     strcpy(FileConfig->FastMacroFileName,LastFastMacros);
  1136.  
  1137.     if(!LastCursorKeys[0])
  1138.     {
  1139.         strcpy(LastCursorKeys,PathBuffer);
  1140.  
  1141.         AddPart(LastCursorKeys,"cursorkeys.prefs",MAX_FILENAME_LENGTH);
  1142.     }
  1143.  
  1144.     strcpy(FileConfig->CursorFileName,LastCursorKeys);
  1145. }
  1146.  
  1147. STATIC VOID
  1148. ResetPath(struct PathSettings *PathConfig,STRPTR PathBuffer)
  1149. {
  1150.     if(!PathBuffer)
  1151.         PathBuffer = "TERM:config";
  1152.  
  1153.     strcpy(PathConfig->DefaultStorage,PathBuffer);
  1154.  
  1155.     strcpy(PathConfig->HelpFile,"PROGDIR:term.guide");
  1156.  
  1157.     strcpy(PathConfig->DefaultStorage,PathBuffer);
  1158.  
  1159.     GetEnvDOS(PathConfig->Editor,"EDITOR");
  1160. }
  1161.  
  1162. STATIC VOID
  1163. ResetMisc(struct MiscSettings *MiscConfig)
  1164. {
  1165.     MiscConfig->Priority            = 1;
  1166.  
  1167.     MiscConfig->ReleaseDevice        = TRUE;
  1168.  
  1169.     MiscConfig->TransferServer        = TRUE;
  1170.     MiscConfig->EmulationServer        = TRUE;
  1171.  
  1172.     MiscConfig->OverridePath        = TRUE;
  1173.     MiscConfig->AutoUpload            = TRUE;
  1174.     MiscConfig->IdentifyFiles        = IDENTIFY_FILETYPE;
  1175.  
  1176.     MiscConfig->IOBufferSize        = 32768;
  1177.  
  1178.     MiscConfig->ProtectiveMode        = TRUE;
  1179.  
  1180.     MiscConfig->AlertMode            = ALERT_BEEP_SCREEN;
  1181.     MiscConfig->RequesterMode        = REQUESTERMODE_IGNORE;
  1182.  
  1183.     strcpy(MiscConfig->WaitString," \\b");
  1184.  
  1185.     MiscConfig->WaitDelay            = 1;    // Just one second
  1186. }
  1187.  
  1188. STATIC VOID
  1189. ResetCommand(struct CommandSettings *CommandConfig)
  1190. {
  1191. }
  1192.  
  1193. STATIC VOID
  1194. ResetTransfer(struct TransferSettings *TransferConfig,STRPTR DefaultLib)
  1195. {
  1196.     LONG i;
  1197.  
  1198.     if(!DefaultLib)
  1199.         strcpy(TransferConfig->DefaultLibrary,"xprzmodem.library");
  1200.     else
  1201.         strcpy(TransferConfig->DefaultLibrary,DefaultLib);
  1202.  
  1203.     for(i = 0 ; i < strlen(TransferConfig->DefaultLibrary) - 6 ; i++)
  1204.     {
  1205.         if(!Strnicmp(&TransferConfig->DefaultLibrary[i],"zmodem",6))
  1206.         {
  1207.             strcpy(TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  1208.  
  1209.             TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  1210.  
  1211.             break;
  1212.         }
  1213.     }
  1214.  
  1215.     strcpy(TransferConfig->ASCIIUploadLibrary,        "xprascii.library");
  1216.     strcpy(TransferConfig->ASCIIDownloadLibrary,    "xprascii.library");
  1217.  
  1218.     strcpy(TransferConfig->BinaryUploadLibrary,"run hydracom device %p speed %b line %c nocarrier rec %> send %m");
  1219.     strcpy(TransferConfig->BinaryDownloadLibrary,"run hydracom device %p speed %b line %c nocarrier rec %> get");
  1220.  
  1221.     TransferConfig->PacingMode                = PACE_DIRECT;
  1222.     TransferConfig->IgnoreDataPastArnold    = TRUE;
  1223.     TransferConfig->TerminatorChar            = 0x1A;
  1224.     TransferConfig->SendCR                    = EOL_CR;
  1225.     TransferConfig->SendLF                    = EOL_LF;
  1226.     TransferConfig->ReceiveCR                = EOL_CR;
  1227.     TransferConfig->ReceiveLF                = EOL_LF;
  1228.  
  1229.     TransferConfig->ErrorNotification        = 20;
  1230.     TransferConfig->TransferNotification    = XFERNOTIFY_ALWAYS;
  1231.  
  1232.     TransferConfig->DefaultType                = XFER_XPR;
  1233.     TransferConfig->ASCIIDownloadType        = XFER_XPR;
  1234.     TransferConfig->ASCIIUploadType            = XFER_XPR;
  1235.     TransferConfig->TextDownloadType        = XFER_DEFAULT;
  1236.     TransferConfig->TextUploadType            = XFER_DEFAULT;
  1237.     TransferConfig->BinaryDownloadType        = XFER_DEFAULT;
  1238.     TransferConfig->BinaryUploadType        = XFER_DEFAULT;
  1239.  
  1240.     TransferConfig->OverridePath            = TRUE;
  1241.     TransferConfig->IdentifyFiles            = IDENTIFY_FILETYPE;
  1242. }
  1243.  
  1244. /*****************************************************************************/
  1245.  
  1246.     /* ResetConfig():
  1247.      *
  1248.      *    Initialize configuration with default values.
  1249.      */
  1250.  
  1251. VOID
  1252. ResetConfig(struct Configuration *Config,STRPTR PathBuffer)
  1253. {
  1254.     LONG    Type;
  1255.     APTR    Data;
  1256.     STRPTR    Arg;
  1257.  
  1258.     if(!PathBuffer)
  1259.         PathBuffer = "TERM:config";
  1260.  
  1261.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1262.     {
  1263.         if(Data = GetConfigEntry(Config,Type))
  1264.         {
  1265.             memset(Data,0,SizeTable[Type - PREF_SERIAL]);
  1266.  
  1267.             switch(Type)
  1268.             {
  1269.                 case PREF_PATH:
  1270.                 case PREF_FILE:
  1271.                 case PREF_TRANSLATIONFILENAME:
  1272.                 case PREF_MACROFILENAME:
  1273.                 case PREF_CURSORFILENAME:
  1274.                 case PREF_FASTMACROFILENAME:
  1275.                 case PREF_SPEECHFILENAME:
  1276.                 case PREF_SOUNDFILENAME:
  1277.                 case PREF_AREACODEFILENAME:
  1278.                 case PREF_PHONEBOOKFILENAME:
  1279.                 case PREF_HOTKEYFILENAME:
  1280.                 case PREF_TRAPFILENAME:
  1281.  
  1282.                     Arg = PathBuffer;
  1283.                     break;
  1284.  
  1285.                 case PREF_TRANSFER:
  1286.  
  1287.                     if(Config->FileConfig)
  1288.                         Arg = Config->FileConfig->ProtocolFileName;
  1289.                     else
  1290.                         Arg = "xprzmodem.library";
  1291.  
  1292.                     break;
  1293.  
  1294.                 default:
  1295.  
  1296.                     Arg = NULL;
  1297.                     break;
  1298.             }
  1299.  
  1300.             (*ResetTable[Type - PREF_SERIAL])(Data,Arg);
  1301.         }
  1302.     }
  1303. }
  1304.  
  1305. VOID
  1306. DeleteConfigEntry(struct Configuration *Config,LONG Type)
  1307. {
  1308.     if(Type == PREF_ALL)
  1309.     {
  1310.         for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1311.             DeleteConfigEntry(Config,Type);
  1312.     }
  1313.     else
  1314.     {
  1315.         APTR *Mem;
  1316.  
  1317.         switch(Type)
  1318.         {
  1319.             case PREF_SERIAL:
  1320.  
  1321.                 Mem = (APTR *)&Config->SerialConfig;
  1322.                 break;
  1323.  
  1324.             case PREF_MODEM:
  1325.  
  1326.                 Mem = (APTR *)&Config->ModemConfig;
  1327.                 break;
  1328.  
  1329.             case PREF_COMMAND:
  1330.  
  1331.                 Mem = (APTR *)&Config->CommandConfig;
  1332.                 break;
  1333.  
  1334.             case PREF_SCREEN:
  1335.  
  1336.                 Mem = (APTR *)&Config->ScreenConfig;
  1337.                 break;
  1338.  
  1339.             case PREF_TERMINAL:
  1340.  
  1341.                 Mem = (APTR *)&Config->TerminalConfig;
  1342.                 break;
  1343.  
  1344.             case PREF_PATH:
  1345.  
  1346.                 Mem = (APTR *)&Config->PathConfig;
  1347.                 break;
  1348.  
  1349.             case PREF_MISC:
  1350.  
  1351.                 Mem = (APTR *)&Config->MiscConfig;
  1352.                 break;
  1353.  
  1354.             case PREF_CLIP:
  1355.  
  1356.                 Mem = (APTR *)&Config->ClipConfig;
  1357.                 break;
  1358.  
  1359.             case PREF_CAPTURE:
  1360.  
  1361.                 Mem = (APTR *)&Config->CaptureConfig;
  1362.                 break;
  1363.  
  1364.             case PREF_FILE:
  1365.  
  1366.                 Mem = (APTR *)&Config->FileConfig;
  1367.                 break;
  1368.  
  1369.             case PREF_EMULATION:
  1370.  
  1371.                 Mem = (APTR *)&Config->EmulationConfig;
  1372.                 break;
  1373.  
  1374.             case PREF_TRANSFER:
  1375.  
  1376.                 Mem = (APTR *)&Config->TransferConfig;
  1377.                 break;
  1378.  
  1379.             case PREF_TRANSLATIONFILENAME:
  1380.  
  1381.                 Mem = (APTR *)&Config->TranslationFileName;
  1382.                 break;
  1383.  
  1384.             case PREF_MACROFILENAME:
  1385.  
  1386.                 Mem = (APTR *)&Config->MacroFileName;
  1387.                 break;
  1388.  
  1389.             case PREF_CURSORFILENAME:
  1390.  
  1391.                 Mem = (APTR *)&Config->CursorFileName;
  1392.                 break;
  1393.  
  1394.             case PREF_FASTMACROFILENAME:
  1395.  
  1396.                 Mem = (APTR *)&Config->FastMacroFileName;
  1397.                 break;
  1398.  
  1399.             case PREF_SPEECHFILENAME:
  1400.  
  1401.                 Mem = (APTR *)&Config->SpeechFileName;
  1402.                 break;
  1403.  
  1404.             case PREF_SOUNDFILENAME:
  1405.  
  1406.                 Mem = (APTR *)&Config->SoundFileName;
  1407.                 break;
  1408.  
  1409.             case PREF_AREACODEFILENAME:
  1410.  
  1411.                 Mem = (APTR *)&Config->AreaCodeFileName;
  1412.                 break;
  1413.  
  1414.             case PREF_PHONEBOOKFILENAME:
  1415.  
  1416.                 Mem = (APTR *)&Config->PhonebookFileName;
  1417.                 break;
  1418.  
  1419.             case PREF_HOTKEYFILENAME:
  1420.  
  1421.                 Mem = (APTR *)&Config->HotkeyFileName;
  1422.                 break;
  1423.  
  1424.             case PREF_TRAPFILENAME:
  1425.  
  1426.                 Mem = (APTR *)&Config->TrapFileName;
  1427.                 break;
  1428.  
  1429.             default:
  1430.  
  1431.                 Mem = NULL;
  1432.                 break;
  1433.         }
  1434.  
  1435.         if(Mem)
  1436.         {
  1437.             FreeVecPooled(*Mem);
  1438.  
  1439.             *Mem = NULL;
  1440.         }
  1441.     }
  1442. }
  1443.  
  1444. VOID
  1445. ResetConfigEntry(struct Configuration *LocalConfig,LONG Type,BOOL Default)
  1446. {
  1447.     if(LocalConfig)
  1448.     {
  1449.         if(Type == PREF_ALL)
  1450.         {
  1451.             for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1452.                 ResetConfigEntry(LocalConfig,Type,Default);
  1453.         }
  1454.         else
  1455.         {
  1456.             if(Type >= PREF_SERIAL && Type < PREF_RATES)
  1457.             {
  1458.                 APTR From,To;
  1459.  
  1460.                 From    = GetConfigEntry(Config,Type);
  1461.                 To        = GetConfigEntry(LocalConfig,Type);
  1462.  
  1463.                 if(To)
  1464.                 {
  1465.                     LONG Size = SizeTable[Type - PREF_SERIAL];
  1466.  
  1467.                     if(Default || !From)
  1468.                     {
  1469.                         memset(To,0,Size);
  1470.  
  1471.                         (*ResetTable[Type - PREF_SERIAL])(To,NULL);
  1472.                     }
  1473.                     else
  1474.                         CopyMem(From,To,Size);
  1475.  
  1476.                     if(Type == PREF_SCREEN)
  1477.                         FixScreenPens(LocalConfig->ScreenConfig);
  1478.                 }
  1479.             }
  1480.         }
  1481.     }
  1482. }
  1483.  
  1484. APTR
  1485. GetConfigEntry(const struct Configuration *Config,LONG Type)
  1486. {
  1487.     if(!Config)
  1488.         return(NULL);
  1489.  
  1490.     switch(Type)
  1491.     {
  1492.         case PREF_SERIAL:
  1493.  
  1494.             return(Config->SerialConfig);
  1495.  
  1496.         case PREF_MODEM:
  1497.  
  1498.             return(Config->ModemConfig);
  1499.  
  1500.         case PREF_COMMAND:
  1501.  
  1502.             return(Config->CommandConfig);
  1503.  
  1504.         case PREF_SCREEN:
  1505.  
  1506.             return(Config->ScreenConfig);
  1507.  
  1508.         case PREF_TERMINAL:
  1509.  
  1510.             return(Config->TerminalConfig);
  1511.  
  1512.         case PREF_PATH:
  1513.  
  1514.             return(Config->PathConfig);
  1515.  
  1516.         case PREF_MISC:
  1517.  
  1518.             return(Config->MiscConfig);
  1519.  
  1520.         case PREF_CLIP:
  1521.  
  1522.             return(Config->ClipConfig);
  1523.  
  1524.         case PREF_CAPTURE:
  1525.  
  1526.             return(Config->CaptureConfig);
  1527.  
  1528.         case PREF_FILE:
  1529.  
  1530.             return(Config->FileConfig);
  1531.  
  1532.         case PREF_EMULATION:
  1533.  
  1534.             return(Config->EmulationConfig);
  1535.  
  1536.         case PREF_TRANSFER:
  1537.  
  1538.             return(Config->TransferConfig);
  1539.  
  1540.         case PREF_TRANSLATIONFILENAME:
  1541.  
  1542.             return(Config->TranslationFileName);
  1543.  
  1544.         case PREF_MACROFILENAME:
  1545.  
  1546.             return(Config->MacroFileName);
  1547.  
  1548.         case PREF_CURSORFILENAME:
  1549.  
  1550.             return(Config->CursorFileName);
  1551.  
  1552.         case PREF_FASTMACROFILENAME:
  1553.  
  1554.             return(Config->FastMacroFileName);
  1555.  
  1556.         case PREF_SPEECHFILENAME:
  1557.  
  1558.             return(Config->SpeechFileName);
  1559.  
  1560.         case PREF_SOUNDFILENAME:
  1561.  
  1562.             return(Config->SoundFileName);
  1563.  
  1564.         case PREF_AREACODEFILENAME:
  1565.  
  1566.             return(Config->AreaCodeFileName);
  1567.  
  1568.         case PREF_PHONEBOOKFILENAME:
  1569.  
  1570.             return(Config->PhonebookFileName);
  1571.  
  1572.         case PREF_HOTKEYFILENAME:
  1573.  
  1574.             return(Config->HotkeyFileName);
  1575.  
  1576.         case PREF_TRAPFILENAME:
  1577.  
  1578.             return(Config->TrapFileName);
  1579.  
  1580.         default:
  1581.  
  1582.             return(NULL);
  1583.     }
  1584. }
  1585.  
  1586. BOOL
  1587. CreateConfigEntry(struct Configuration *Config,LONG Type)
  1588. {
  1589.     if(Type == PREF_ALL)
  1590.     {
  1591.         for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1592.         {
  1593.             if(!CreateConfigEntry(Config,Type))
  1594.             {
  1595.                 DeleteConfigEntry(Config,PREF_ALL);
  1596.  
  1597.                 return(FALSE);
  1598.             }
  1599.         }
  1600.     }
  1601.     else
  1602.     {
  1603.         APTR Data;
  1604.  
  1605.         if(Type < PREF_SERIAL || Type >= PREF_RATES)
  1606.             return(FALSE);
  1607.         else
  1608.         {
  1609.             if(!(Data = GetConfigEntry(Config,Type)))
  1610.             {
  1611.                 DB(kprintf("creating config entry %ld, size = %ld\n",Type,SizeTable[Type - PREF_SERIAL]));
  1612.  
  1613.                 if(!(Data = AllocVecPooled(SizeTable[Type - PREF_SERIAL],MEMF_ANY | MEMF_CLEAR)))
  1614.                 {
  1615.                     DB(kprintf("\tallocation failed\n"));
  1616.                     return(FALSE);
  1617.                 }
  1618.                 else
  1619.                 {
  1620.                     DB(kprintf("\tok\n"));
  1621.  
  1622.                     switch(Type)
  1623.                     {
  1624.                         case PREF_SERIAL:
  1625.  
  1626.                             Config->SerialConfig = Data;
  1627.                             break;
  1628.  
  1629.                         case PREF_MODEM:
  1630.  
  1631.                             Config->ModemConfig = Data;
  1632.                             break;
  1633.  
  1634.                         case PREF_COMMAND:
  1635.  
  1636.                             Config->CommandConfig = Data;
  1637.                             break;
  1638.  
  1639.                         case PREF_SCREEN:
  1640.  
  1641.                             Config->ScreenConfig = Data;
  1642.                             break;
  1643.  
  1644.                         case PREF_TERMINAL:
  1645.  
  1646.                             Config->TerminalConfig = Data;
  1647.                             break;
  1648.  
  1649.                         case PREF_PATH:
  1650.  
  1651.                             Config->PathConfig = Data;
  1652.                             break;
  1653.  
  1654.                         case PREF_MISC:
  1655.  
  1656.                             Config->MiscConfig = Data;
  1657.                             break;
  1658.  
  1659.                         case PREF_CLIP:
  1660.  
  1661.                             Config->ClipConfig = Data;
  1662.                             break;
  1663.  
  1664.                         case PREF_CAPTURE:
  1665.  
  1666.                             Config->CaptureConfig = Data;
  1667.                             break;
  1668.  
  1669.                         case PREF_FILE:
  1670.  
  1671.                             Config->FileConfig = Data;
  1672.                             break;
  1673.  
  1674.                         case PREF_EMULATION:
  1675.  
  1676.                             Config->EmulationConfig = Data;
  1677.                             break;
  1678.  
  1679.                         case PREF_TRANSFER:
  1680.  
  1681.                             Config->TransferConfig = Data;
  1682.                             break;
  1683.  
  1684.                         case PREF_TRANSLATIONFILENAME:
  1685.  
  1686.                             Config->TranslationFileName = Data;
  1687.                             break;
  1688.  
  1689.                         case PREF_MACROFILENAME:
  1690.  
  1691.                             Config->MacroFileName = Data;
  1692.                             break;
  1693.  
  1694.                         case PREF_CURSORFILENAME:
  1695.  
  1696.                             Config->CursorFileName = Data;
  1697.                             break;
  1698.  
  1699.                         case PREF_FASTMACROFILENAME:
  1700.  
  1701.                             Config->FastMacroFileName = Data;
  1702.                             break;
  1703.  
  1704.                         case PREF_SPEECHFILENAME:
  1705.  
  1706.                             Config->SpeechFileName = Data;
  1707.                             break;
  1708.  
  1709.                         case PREF_SOUNDFILENAME:
  1710.  
  1711.                             Config->SoundFileName = Data;
  1712.                             break;
  1713.  
  1714.                         case PREF_AREACODEFILENAME:
  1715.  
  1716.                             Config->AreaCodeFileName = Data;
  1717.                             break;
  1718.  
  1719.                         case PREF_PHONEBOOKFILENAME:
  1720.  
  1721.                             Config->PhonebookFileName = Data;
  1722.                             break;
  1723.  
  1724.                         case PREF_HOTKEYFILENAME:
  1725.  
  1726.                             Config->HotkeyFileName = Data;
  1727.                             break;
  1728.  
  1729.                         case PREF_TRAPFILENAME:
  1730.  
  1731.                             Config->TrapFileName = Data;
  1732.                             break;
  1733.                     }
  1734.  
  1735.                     DB(kprintf("\tresetting\n"));
  1736.                     ResetConfigEntry(Config,Type,FALSE);
  1737.                     DB(kprintf("\tdone\n"));
  1738.                 }
  1739.             }
  1740.         }
  1741.     }
  1742.  
  1743.     return(TRUE);
  1744. }
  1745.  
  1746. VOID
  1747. DeleteConfiguration(struct Configuration *Config)
  1748. {
  1749.     if(Config)
  1750.     {
  1751.         DeleteConfigEntry(Config,PREF_ALL);
  1752.  
  1753.         FreeVecPooled(Config);
  1754.     }
  1755. }
  1756.  
  1757. struct Configuration *
  1758. CreateConfiguration(BOOL Fill)
  1759. {
  1760.     struct Configuration *Config;
  1761.  
  1762.     if(Config = (struct Configuration *)AllocVecPooled(sizeof(struct Configuration),MEMF_ANY | MEMF_CLEAR))
  1763.     {
  1764.         if(Fill)
  1765.         {
  1766.             if(!CreateConfigEntry(Config,PREF_ALL))
  1767.             {
  1768.                 FreeVecPooled(Config);
  1769.  
  1770.                 return(NULL);
  1771.             }
  1772.         }
  1773.  
  1774.         return(Config);
  1775.     }
  1776.     else
  1777.         return(NULL);
  1778. }
  1779.  
  1780. STATIC BOOL
  1781. WriteConfigChunk(struct IFFHandle *Handle,struct Configuration *Config,LONG Type,APTR TempBuffer,STRPTR Password)
  1782. {
  1783.     if(Type >= PREF_SERIAL && Type < PREF_RATES && Type != PREF_FILE)
  1784.     {
  1785.         APTR Data;
  1786.  
  1787.         if(Data = GetConfigEntry(Config,Type))
  1788.         {
  1789.             if(TempBuffer)
  1790.             {
  1791.                 Encrypt(Data,SizeTable[Type - PREF_SERIAL],TempBuffer,Password,20);
  1792.  
  1793.                 Data = TempBuffer;
  1794.             }
  1795.  
  1796.             if(!PushChunk(Handle,0,TypeTable[Type - PREF_SERIAL],SizeTable[Type - PREF_SERIAL]))
  1797.             {
  1798.                 if(WriteChunkRecords(Handle,Data,SizeTable[Type - PREF_SERIAL],1) == 1)
  1799.                 {
  1800.                     if(!PopChunk(Handle))
  1801.                         return(TRUE);
  1802.                 }
  1803.             }
  1804.  
  1805.             return(FALSE);
  1806.         }
  1807.     }
  1808.  
  1809.     return(TRUE);
  1810. }
  1811.  
  1812. STATIC LONG
  1813. IsConfigChunk(ULONG ID)
  1814. {
  1815.     LONG Type;
  1816.  
  1817.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1818.     {
  1819.         if(ID == TypeTable[Type - PREF_SERIAL])
  1820.             return(Type);
  1821.     }
  1822.  
  1823.     return(0);
  1824. }
  1825.  
  1826. STATIC BOOL
  1827. WriteConfigChunks(struct IFFHandle *Handle,struct Configuration *Config,APTR TempBuffer,STRPTR Password)
  1828. {
  1829.     LONG Type;
  1830.  
  1831.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1832.     {
  1833.         if(!WriteConfigChunk(Handle,Config,Type,TempBuffer,Password))
  1834.             return(FALSE);
  1835.     }
  1836.  
  1837.     return(TRUE);
  1838. }
  1839.  
  1840. VOID
  1841. SaveConfig(const struct Configuration *Src,struct Configuration *Dst)
  1842. {
  1843.     APTR From,To;
  1844.     LONG Type;
  1845.  
  1846.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1847.     {
  1848.         if((From = GetConfigEntry(Src,Type)) && (To = GetConfigEntry(Dst,Type)))
  1849.         {
  1850.             CopyMem(From,To,SizeTable[Type - PREF_SERIAL]);
  1851.  
  1852.             if(Type == PREF_SCREEN)
  1853.                 FixScreenPens(To);
  1854.         }
  1855.     }
  1856. }
  1857.  
  1858. VOID
  1859. UpdateConfig(const struct Configuration *Src,struct Configuration *Dst)
  1860. {
  1861.     SaveConfig(Src,Dst);
  1862. }
  1863.  
  1864. VOID
  1865. SwapConfig(struct Configuration *Src,struct Configuration *Dst)
  1866. {
  1867.     APTR From,To;
  1868.     LONG Type;
  1869.  
  1870.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1871.     {
  1872.         if((From = GetConfigEntry(Src,Type)) && (To = GetConfigEntry(Dst,Type)))
  1873.             swmem(From,To,SizeTable[Type - PREF_SERIAL]);
  1874.     }
  1875. }
  1876.  
  1877.     /* SavePhonebook(STRPTR Name):
  1878.      *
  1879.      *    Save the current phone book to a disk file.
  1880.      */
  1881.  
  1882. BOOL
  1883. SavePhonebook(STRPTR Name)
  1884. {
  1885.     struct IFFHandle    *Handle;
  1886.     BOOL                 Success = FALSE;
  1887.     LONG                 Error = 0;
  1888.  
  1889. #ifdef BETA
  1890.     if(ShowRequest(Window,
  1891.         "ONE WAY TICKET WARNING!\n\n"
  1892.         "The file format written by this `term' beta test release\n"
  1893.         "cannot be read by older program releases. And just as it\n"
  1894.         "happens, not even the author of these lines can guarantee\n"
  1895.         "you that this very program will be able to read the files\n"
  1896.         "back it writes.",
  1897.     "Uh oh...|I know what I'm doing"))
  1898.         return(TRUE);
  1899. #endif
  1900.  
  1901.     if(Phonebook && NumPhoneEntries)
  1902.     {
  1903.         if(Handle = (struct IFFHandle *)AllocIFF())
  1904.         {
  1905.             if(Handle->iff_Stream = Open(Name,MODE_NEWFILE))
  1906.             {
  1907.                 InitIFFasDOS(Handle);
  1908.  
  1909.                 if(!(Error = OpenIFF(Handle,IFFF_WRITE)))
  1910.                 {
  1911.                     if(!(Error = PushChunk(Handle,ID_TERM,ID_CAT,IFFSIZE_UNKNOWN)))
  1912.                     {
  1913.                         if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  1914.                         {
  1915.                             if(!(Error = PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN)))
  1916.                             {
  1917.                                 struct TermInfo TermInfo;
  1918.  
  1919.                                 TermInfo.Version    = CONFIG_FILE_VERSION;
  1920.                                 TermInfo.Revision    = CONFIG_FILE_REVISION;
  1921.  
  1922.                                 if(WriteChunkRecords(Handle,&TermInfo,sizeof(struct TermInfo),1) == 1)
  1923.                                 {
  1924.                                     if(!(Error = PopChunk(Handle)))
  1925.                                     {
  1926.                                         STRPTR TempBuffer = NULL;
  1927.  
  1928.                                         if(PhonePasswordUsed)
  1929.                                         {
  1930.                                             if(!(Error = PushChunk(Handle,0,ID_PSWD,20)))
  1931.                                             {
  1932.                                                 Success = TRUE;
  1933.  
  1934.                                                 if(WriteChunkBytes(Handle,PhonePassword,20) != 20)
  1935.                                                     Success = FALSE;
  1936.  
  1937.                                                 if(PopChunk(Handle))
  1938.                                                     Success = FALSE;
  1939.  
  1940.                                                 if(Success)
  1941.                                                 {
  1942.                                                     LONG Max = sizeof(struct PhoneHeader);
  1943.                                                     LONG Type;
  1944.  
  1945.                                                     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1946.                                                     {
  1947.                                                         if(SizeTable[Type - PREF_SERIAL] > Max)
  1948.                                                             Max = SizeTable[Type - PREF_SERIAL];
  1949.                                                     }
  1950.  
  1951.                                                     if(!(TempBuffer = AllocVecPooled(Max,MEMF_ANY)))
  1952.                                                     {
  1953.                                                         Error = ERR_NO_MEM;
  1954.  
  1955.                                                         Success = FALSE;
  1956.                                                     }
  1957.                                                 }
  1958.                                             }
  1959.                                         }
  1960.                                         else
  1961.                                             Success = TRUE;
  1962.  
  1963.                                         if(Success)
  1964.                                         {
  1965.                                             Success = FALSE;
  1966.  
  1967.                                             if(!(Error = PushChunk(Handle,0,ID_DIAL,IFFSIZE_UNKNOWN)))
  1968.                                             {
  1969.                                                 PhonebookGlobals Globals;
  1970.  
  1971.                                                 Globals.Count            = NumPhoneEntries;
  1972.                                                 Globals.ID                = PhonebookID;
  1973.                                                 Globals.DefaultGroup    = PhonebookDefaultGroup;
  1974.                                                 Globals.AutoDial        = PhonebookAutoDial;
  1975.                                                 Globals.AutoExit        = PhonebookAutoExit;
  1976.  
  1977.                                                 if(WriteChunkBytes(Handle,&Globals,sizeof(Globals)) == sizeof(Globals))
  1978.                                                 {
  1979.                                                     if(!(Error = PopChunk(Handle)))
  1980.                                                     {
  1981.                                                         if(!(Error = PopChunk(Handle)))
  1982.                                                         {
  1983.                                                             LONG i;
  1984.  
  1985.                                                             Success = TRUE;
  1986.  
  1987.                                                             for(i = 0 ; Success && i < NumPhoneEntries ; i++)
  1988.                                                             {
  1989.                                                                 Success = FALSE;
  1990.  
  1991.                                                                 if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  1992.                                                                 {
  1993.                                                                     if(!(Error = PushChunk(Handle,0,ID_PHON,sizeof(struct PhoneHeader))))
  1994.                                                                     {
  1995.                                                                         if(TempBuffer)
  1996.                                                                         {
  1997.                                                                             Encrypt((UBYTE *)Phonebook[i]->Header,sizeof(struct PhoneHeader),TempBuffer,PhonePassword,20);
  1998.  
  1999.                                                                             if(WriteChunkRecords(Handle,TempBuffer,sizeof(struct PhoneHeader),1) == 1)
  2000.                                                                             {
  2001.                                                                                 if(!(Error = PopChunk(Handle)))
  2002.                                                                                 {
  2003.                                                                                     if(WriteConfigChunks(Handle,Phonebook[i]->Config,TempBuffer,PhonePassword))
  2004.                                                                                     {
  2005.                                                                                         Success = TRUE;
  2006.  
  2007.                                                                                         if(!Phonebook[i]->Header->NoRates)
  2008.                                                                                         {
  2009.                                                                                             struct TimeDateNode *TimeDateNode;
  2010.  
  2011.                                                                                             TimeDateNode = (struct TimeDateNode *)Phonebook[i]->TimeDateList.mlh_Head;
  2012.  
  2013.                                                                                             while(TimeDateNode->VanillaNode.ln_Succ)
  2014.                                                                                             {
  2015.                                                                                                 if(!(Error = PushChunk(Handle,0,ID_DAT2,IFFSIZE_UNKNOWN)))
  2016.                                                                                                 {
  2017.                                                                                                     if(WriteChunkBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)) != sizeof(struct TimeDateHeader))
  2018.                                                                                                     {
  2019.                                                                                                         Error = IoErr();
  2020.  
  2021.                                                                                                         Success = FALSE;
  2022.  
  2023.                                                                                                         break;
  2024.                                                                                                     }
  2025.                                                                                                     else
  2026.                                                                                                     {
  2027.                                                                                                         if(WriteChunkBytes(Handle,TimeDateNode->Table,TimeDateNode->Table[0].Count * sizeof(struct TimeDate)) != TimeDateNode->Table[0].Count * sizeof(struct TimeDate))
  2028.                                                                                                         {
  2029.                                                                                                             Error = IoErr();
  2030.  
  2031.                                                                                                             Success = FALSE;
  2032.  
  2033.                                                                                                             break;
  2034.                                                                                                         }
  2035.                                                                                                     }
  2036.  
  2037.                                                                                                     if(Success)
  2038.                                                                                                     {
  2039.                                                                                                         if(Error = PopChunk(Handle))
  2040.                                                                                                         {
  2041.                                                                                                             Success = FALSE;
  2042.  
  2043.                                                                                                             break;
  2044.                                                                                                         }
  2045.                                                                                                     }
  2046.  
  2047.                                                                                                     TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode.ln_Succ;
  2048.                                                                                                 }
  2049.                                                                                             }
  2050.                                                                                         }
  2051.                                                                                     }
  2052.                                                                                     else
  2053.                                                                                     {
  2054.                                                                                         Error = IoErr();
  2055.  
  2056.                                                                                         Success = FALSE;
  2057.                                                                                     }
  2058.                                                                                 }
  2059.                                                                             }
  2060.                                                                             else
  2061.                                                                                 Error = IoErr();
  2062.                                                                         }
  2063.                                                                         else
  2064.                                                                         {
  2065.                                                                             if(WriteChunkRecords(Handle,Phonebook[i]->Header,sizeof(struct PhoneHeader),1) == 1)
  2066.                                                                             {
  2067.                                                                                 if(!(Error = PopChunk(Handle)))
  2068.                                                                                 {
  2069.                                                                                     if(WriteConfigChunks(Handle,Phonebook[i]->Config,NULL,NULL))
  2070.                                                                                     {
  2071.                                                                                         Success = TRUE;
  2072.  
  2073.                                                                                         if(!Phonebook[i]->Header->NoRates)
  2074.                                                                                         {
  2075.                                                                                             struct TimeDateNode *TimeDateNode;
  2076.  
  2077.                                                                                             TimeDateNode = (struct TimeDateNode *)Phonebook[i]->TimeDateList.mlh_Head;
  2078.  
  2079.                                                                                             while(TimeDateNode->VanillaNode.ln_Succ)
  2080.                                                                                             {
  2081.                                                                                                 if(!(Error = PushChunk(Handle,0,ID_DAT2,IFFSIZE_UNKNOWN)))
  2082.                                                                                                 {
  2083.                                                                                                     if(WriteChunkBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)) != sizeof(struct TimeDateHeader))
  2084.                                                                                                     {
  2085.                                                                                                         Error = IoErr();
  2086.  
  2087.                                                                                                         Success = FALSE;
  2088.  
  2089.                                                                                                         break;
  2090.                                                                                                     }
  2091.                                                                                                     else
  2092.                                                                                                     {
  2093.                                                                                                         if(WriteChunkBytes(Handle,TimeDateNode->Table,TimeDateNode->Table[0].Count * sizeof(struct TimeDate)) != TimeDateNode->Table[0].Count * sizeof(struct TimeDate))
  2094.                                                                                                         {
  2095.                                                                                                             Error = IoErr();
  2096.  
  2097.                                                                                                             Success = FALSE;
  2098.  
  2099.                                                                                                             break;
  2100.                                                                                                         }
  2101.                                                                                                     }
  2102.  
  2103.                                                                                                     if(Success)
  2104.                                                                                                     {
  2105.                                                                                                         if(Error = PopChunk(Handle))
  2106.                                                                                                         {
  2107.                                                                                                             Success = FALSE;
  2108.  
  2109.                                                                                                             break;
  2110.                                                                                                         }
  2111.                                                                                                     }
  2112.  
  2113.                                                                                                     TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode.ln_Succ;
  2114.                                                                                                 }
  2115.                                                                                             }
  2116.                                                                                         }
  2117.                                                                                     }
  2118.                                                                                     else
  2119.                                                                                     {
  2120.                                                                                         Success = FALSE;
  2121.  
  2122.                                                                                         Error = IoErr();
  2123.                                                                                     }
  2124.                                                                                 }
  2125.                                                                             }
  2126.                                                                             else
  2127.                                                                                 Error = IoErr();
  2128.                                                                         }
  2129.                                                                     }
  2130.  
  2131.                                                                     if(Success)
  2132.                                                                     {
  2133.                                                                         if(Error = PopChunk(Handle))
  2134.                                                                             Success = FALSE;
  2135.                                                                     }
  2136.                                                                 }
  2137.                                                             }
  2138.  
  2139.                                                                 // Now for the groups
  2140.  
  2141.                                                             if(Success && PhoneGroupList.mlh_Head->mln_Succ)
  2142.                                                             {
  2143.                                                                 struct PhoneGroupNode    *GroupNode;
  2144.                                                                 struct PhoneNode        *Node;
  2145.                                                                 PhoneGroupHeader         Header;
  2146.                                                                 BOOL                     GotData = FALSE;
  2147.  
  2148.                                                                     // So the extension stuff is set to zero
  2149.  
  2150.                                                                 memset(&Header,0,sizeof(Header));
  2151.  
  2152.                                                                     // Run down the groups
  2153.  
  2154.                                                                 for(GroupNode = (PhoneGroupNode *)PhoneGroupList.mlh_Head ; Success && GroupNode->Node.ln_Succ ; GroupNode = (PhoneGroupNode *)GroupNode->Node.ln_Succ)
  2155.                                                                 {
  2156.                                                                         // Count the members
  2157.  
  2158.                                                                     Header.Count = 0;
  2159.  
  2160.                                                                     for(Node = (struct PhoneNode *)GroupNode->GroupList.mlh_Head ; Node->VanillaNode.ln_Succ ; Node = (struct PhoneNode *)Node->VanillaNode.ln_Succ)
  2161.                                                                         Header.Count++;
  2162.  
  2163.                                                                         // Open the group
  2164.  
  2165.                                                                     if(Header.Count)
  2166.                                                                     {
  2167.                                                                         if(!GotData)
  2168.                                                                         {
  2169.                                                                             if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  2170.                                                                                 GotData = TRUE;
  2171.                                                                         }
  2172.  
  2173.                                                                             // Pick up the group name
  2174.  
  2175.                                                                         strcpy(Header.FullName,GroupNode->LocalName);
  2176.  
  2177.                                                                         if(!Error)
  2178.                                                                             Error = PushChunk(Handle,0,ID_GRUP,sizeof(Header) + sizeof(LONG) * Header.Count);
  2179.  
  2180.                                                                         if(!Error)
  2181.                                                                         {
  2182.                                                                                 // First the header...
  2183.  
  2184.                                                                             if(WriteChunkBytes(Handle,&Header,sizeof(Header)) == sizeof(Header))
  2185.                                                                             {
  2186.                                                                                     // ...then the IDs of the group members
  2187.  
  2188.                                                                                 for(Node = (struct PhoneNode *)GroupNode->GroupList.mlh_Head ; Node->VanillaNode.ln_Succ ; Node = (struct PhoneNode *)Node->VanillaNode.ln_Succ)
  2189.                                                                                 {
  2190.                                                                                     if(WriteChunkBytes(Handle,&Node->Entry->Header->ID,sizeof(ULONG)) != sizeof(ULONG))
  2191.                                                                                     {
  2192.                                                                                         Success = FALSE;
  2193.                                                                                         break;
  2194.                                                                                     }
  2195.                                                                                 }
  2196.  
  2197.                                                                                 if(!Success)
  2198.                                                                                 {
  2199.                                                                                     Error = IoErr();
  2200.                                                                                     break;
  2201.                                                                                 }
  2202.                                                                             }
  2203.                                                                             else
  2204.                                                                             {
  2205.                                                                                 Error = IoErr();
  2206.                                                                                 Success = FALSE;
  2207.                                                                                 break;
  2208.                                                                             }
  2209.  
  2210.                                                                             if(Error = PopChunk(Handle))
  2211.                                                                                 Success = FALSE;
  2212.                                                                         }
  2213.                                                                         else
  2214.                                                                             Success = FALSE;
  2215.                                                                     }
  2216.                                                                 }
  2217.  
  2218.                                                                 if(Success && GotData)
  2219.                                                                 {
  2220.                                                                     if(Error = PopChunk(Handle))
  2221.                                                                         Success = FALSE;
  2222.                                                                 }
  2223.                                                             }
  2224.                                                         }
  2225.                                                     }
  2226.                                                 }
  2227.                                                 else
  2228.                                                     Error = IoErr();
  2229.                                             }
  2230.                                         }
  2231.  
  2232.                                         if(TempBuffer)
  2233.                                             FreeVecPooled(TempBuffer);
  2234.                                     }
  2235.                                 }
  2236.                                 else
  2237.                                     Error = IoErr();
  2238.                             }
  2239.                         }
  2240.  
  2241.                         if(Success)
  2242.                         {
  2243.                             if(Error = PopChunk(Handle))
  2244.                                 Success = FALSE;
  2245.                         }
  2246.                     }
  2247.  
  2248.                     CloseIFF(Handle);
  2249.                 }
  2250.  
  2251.                 Close(Handle->iff_Stream);
  2252.             }
  2253.             else
  2254.                 Error = IoErr();
  2255.  
  2256.             FreeIFF(Handle);
  2257.         }
  2258.         else
  2259.             Error = ERR_NO_MEM;
  2260.  
  2261.         if(Success)
  2262.             AddProtection(Name,FIBF_EXECUTE);
  2263.         else
  2264.             DeleteFile(Name);
  2265.     }
  2266.  
  2267.     if(Error)
  2268.         SetIoErr(Error);
  2269.  
  2270.     return(Success);
  2271. }
  2272.  
  2273. STATIC BOOL
  2274. ReadConfigChunk(struct IFFHandle *Handle,struct Configuration *Config,LONG Type,LONG Len,STRPTR Password)
  2275. {
  2276.     if(CreateConfigEntry(Config,Type))
  2277.     {
  2278.         APTR Data;
  2279.  
  2280.         Data = GetConfigEntry(Config,Type);
  2281.  
  2282.         Len = MIN(SizeTable[Type - PREF_SERIAL],Len);
  2283.  
  2284.         if(ReadChunkBytes(Handle,Data,Len) == Len)
  2285.         {
  2286.             if(Password)
  2287.                 Decrypt(Data,Len,Data,Password,20);
  2288.  
  2289.             if(Type == PREF_SCREEN)
  2290.                 FixScreenPens(Data);
  2291.  
  2292.             return(TRUE);
  2293.         }
  2294.     }
  2295.  
  2296.     return(FALSE);
  2297. }
  2298.  
  2299.     /* LoadPhonebook(STRPTR Name):
  2300.      *
  2301.      *    Restore a phone book from a disk file.
  2302.      */
  2303.  
  2304. BOOL
  2305. LoadPhonebook(STRPTR Name,PhonebookHandle *BookHandle)
  2306. {
  2307.     struct PhoneEntry    **PrivatePhonebook;
  2308.     LONG                 PrivatePhoneSize    = 0,
  2309.                          CurrentPhoneSize    = 0,
  2310.                          Count                = 0,
  2311.                          Index                = 0;
  2312.     BOOL                 Success            = FALSE,
  2313.                          LastHadTime        = TRUE,
  2314.                          UsePhonePassword    = FALSE,
  2315.                          FirstChunk            = TRUE,
  2316.                          UseOld                = FALSE;
  2317.     struct IFFHandle    *Handle;
  2318.     struct ContextNode    *Chunk;
  2319.     struct TimeDateNode    *TimeDateNode;
  2320.     UBYTE                 ConfigChunkType,
  2321.                          PasswordBuffer[20];
  2322.     LONG                 Error;
  2323.     PhonebookGlobals     Globals;
  2324.     struct timeval         Now;
  2325.     ULONG                 PrivatePhonebookID;
  2326.     struct MinList         LocalPhoneGroupList;
  2327.     BOOL                 CheckedChunk = FALSE;
  2328.     BOOL                 GotID = FALSE;
  2329.  
  2330.     NewList((struct List *)&LocalPhoneGroupList);
  2331.  
  2332.     GetSysTime(&Now);
  2333.  
  2334.     memset(&Globals,0,sizeof(Globals));
  2335.  
  2336.     Globals.ID                = Now.tv_secs;
  2337.     Globals.DefaultGroup    = 0;
  2338.     Globals.AutoDial        = 0;
  2339.     Globals.AutoExit        = 0;
  2340.  
  2341.     if(Handle = AllocIFF())
  2342.     {
  2343.         if(Handle->iff_Stream = Open(Name,MODE_OLDFILE))
  2344.         {
  2345.             InitIFFasDOS(Handle);
  2346.  
  2347.             if(!(Error = OpenIFF(Handle,IFFF_READ)))
  2348.             {
  2349.                 if(!(Error = StopChunks(Handle,Stops,NUM_STOPS)))
  2350.                 {
  2351.                     struct TermInfo TermInfo;
  2352.  
  2353.                     while(!ParseIFF(Handle,IFFPARSE_SCAN))
  2354.                     {
  2355.                         Chunk = CurrentChunk(Handle);
  2356.  
  2357.                             /* Is this the first chunk to be read? */
  2358.  
  2359.                         if(!CheckedChunk)
  2360.                         {
  2361.                                 /* The first chunk must be a
  2362.                                  * catalog chunk, or this is
  2363.                                  * not a proper phonebook file.
  2364.                                  */
  2365.  
  2366.                             if(Chunk->cn_ID != ID_CAT)
  2367.                                 break;
  2368.                             else
  2369.                                 CheckedChunk = TRUE;
  2370.                         }
  2371.  
  2372.                         if(Chunk->cn_ID == ID_VERS)
  2373.                         {
  2374.                             if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  2375.                             {
  2376.                                 if(TermInfo.Version != CONFIG_FILE_VERSION || (TermInfo.Version == CONFIG_FILE_VERSION && TermInfo.Revision > CONFIG_FILE_REVISION))
  2377.                                 {
  2378.                                     if(TermInfo.Version == 2 && TermInfo.Revision == 4)
  2379.                                         UseOld = TRUE;
  2380.  
  2381.                                     if(TermInfo.Version != 3)
  2382.                                         break;
  2383.                                 }
  2384.                             }
  2385.                             else
  2386.                             {
  2387.                                 Error = IoErr();
  2388.  
  2389.                                 break;
  2390.                             }
  2391.                         }
  2392.  
  2393.                         if(Chunk->cn_ID == ID_PSWD)
  2394.                         {
  2395.                             if(ReadChunkBytes(Handle,PasswordBuffer,20) == 20)
  2396.                             {
  2397.                                 if(BookHandle)
  2398.                                 {
  2399.                                     if(BookHandle->PhonePasswordUsed)
  2400.                                     {
  2401.                                         if(!memcmp(BookHandle->PhonePassword,PasswordBuffer,20))
  2402.                                         {
  2403.                                             UsePhonePassword = TRUE;
  2404.  
  2405.                                             continue;
  2406.                                         }
  2407.                                     }
  2408.                                 }
  2409.                                 else
  2410.                                 {
  2411.                                     if(PhonePasswordUsed)
  2412.                                     {
  2413.                                         if(!memcmp(PhonePassword,PasswordBuffer,20))
  2414.                                         {
  2415.                                             UsePhonePassword = TRUE;
  2416.  
  2417.                                             continue;
  2418.                                         }
  2419.                                     }
  2420.                                 }
  2421.  
  2422.                                 memset(SharedBuffer,0,21);
  2423.  
  2424.                                 if(GetString(FALSE,TRUE,21,LocaleString(MSG_PHONEPANEL_PLEASE_ENTER_PASSWORD_TXT),SharedBuffer))
  2425.                                 {
  2426.                                     UBYTE AnotherBuffer[20];
  2427.  
  2428.                                     Encrypt(SharedBuffer,20,AnotherBuffer,SharedBuffer,strlen(SharedBuffer));
  2429.  
  2430.                                     if(!memcmp(PasswordBuffer,AnotherBuffer,20))
  2431.                                     {
  2432.                                         UsePhonePassword = TRUE;
  2433.  
  2434.                                         continue;
  2435.                                     }
  2436.                                     else
  2437.                                     {
  2438.                                         ShowRequest(Window,LocaleString(MSG_TERMPHONE_WRONG_PASSWORD_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Name);
  2439.  
  2440.                                         break;
  2441.                                     }
  2442.                                 }
  2443.                                 else
  2444.                                     break;
  2445.                             }
  2446.                             else
  2447.                             {
  2448.                                 Error = IoErr();
  2449.  
  2450.                                 break;
  2451.                             }
  2452.                         }
  2453.  
  2454.                         if(Chunk->cn_ID == ID_DIAL)
  2455.                         {
  2456.                             LONG Size = MIN(sizeof(PhonebookGlobals),Chunk->cn_Size);
  2457.  
  2458.                             if(ReadChunkBytes(Handle,&Globals,Size) == Size)
  2459.                             {
  2460.                                 CurrentPhoneSize = Globals.Count;
  2461.  
  2462.                                 if(Size >= sizeof(PhonebookGlobals))
  2463.                                     GotID = TRUE;
  2464.  
  2465.                                 PrivatePhonebookID = Globals.ID;
  2466.  
  2467.                                 if(!CurrentPhoneSize)
  2468.                                     break;
  2469.                                 else
  2470.                                 {
  2471.                                     if(!(PrivatePhonebook = CreatePhonebook(CurrentPhoneSize,&PrivatePhoneSize,TRUE)))
  2472.                                     {
  2473.                                         Error = ERR_NO_MEM;
  2474.  
  2475.                                         break;
  2476.                                     }
  2477.                                 }
  2478.                             }
  2479.                             else
  2480.                             {
  2481.                                 Error = IoErr();
  2482.  
  2483.                                 break;
  2484.                             }
  2485.                         }
  2486.  
  2487.                         if(Chunk->cn_ID == ID_PHON)
  2488.                         {
  2489.                             LONG Size = MIN(sizeof(struct PhoneHeader),Chunk->cn_Size);
  2490.  
  2491.                             if(!CurrentPhoneSize)
  2492.                                 break;
  2493.  
  2494.                             if(!LastHadTime)
  2495.                             {
  2496.                                 if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
  2497.                                     AddTail((struct List *)&PrivatePhonebook[Index]->TimeDateList,&TimeDateNode->VanillaNode);
  2498.                             }
  2499.  
  2500.                             if(!FirstChunk)
  2501.                                 Index++;
  2502.                             else
  2503.                                 FirstChunk = FALSE;
  2504.  
  2505.                             memset(PrivatePhonebook[Index]->Header,0,sizeof(struct PhoneHeader));
  2506.  
  2507.                             if(ReadChunkBytes(Handle,PrivatePhonebook[Index]->Header,Size) == Size)
  2508.                             {
  2509.                                 if(UsePhonePassword)
  2510.                                     Decrypt((UBYTE *)PrivatePhonebook[Index]->Header,Size,(UBYTE *)PrivatePhonebook[Index]->Header,PasswordBuffer,20);
  2511.  
  2512.                                 PrivatePhonebook[Index]->Count = -1;
  2513.  
  2514.                                 if(!GotID)
  2515.                                     PrivatePhonebook[Index]->Header->ID = PrivatePhonebookID++;
  2516.  
  2517.                                 LastHadTime = FALSE;
  2518.  
  2519.                                 Count++;
  2520.                             }
  2521.                             else
  2522.                             {
  2523.                                 Error = IoErr();
  2524.  
  2525.                                 break;
  2526.                             }
  2527.                         }
  2528.  
  2529.                             // Mucho importante -- must follow the phonebook entries
  2530.  
  2531.                         if(Chunk->cn_ID == ID_GRUP)
  2532.                         {
  2533.                             PhoneGroupHeader     Header;
  2534.                             struct MinList        *GroupList;
  2535.  
  2536.                             DB(kprintf("--> ID_GRUP\n"));
  2537.  
  2538.                             if(BookHandle)
  2539.                                 GroupList = BookHandle->PhoneGroupList;
  2540.                             else
  2541.                                 GroupList = &LocalPhoneGroupList;
  2542.  
  2543.                             if(GroupList)
  2544.                             {
  2545.                                 if(ReadChunkBytes(Handle,&Header,sizeof(Header)) == sizeof(Header))
  2546.                                 {
  2547.                                     PhoneGroupNode    *GroupNode;
  2548.                                     ULONG             ID;
  2549.                                     LONG             i;
  2550.  
  2551.                                     GroupNode = NULL;
  2552.  
  2553.                                     Success = TRUE;
  2554.  
  2555.                                     DB(kprintf("group name |%s| entries %ld\n",Header.FullName,Header.Count));
  2556.  
  2557.                                     for(i = 0 ; Success && i < Header.Count ; i++)
  2558.                                     {
  2559.                                         if(ReadChunkBytes(Handle,&ID,sizeof(ULONG)) == sizeof(ULONG))
  2560.                                         {
  2561.                                             struct PhoneNode    *Node;
  2562.                                             LONG                 j;
  2563.  
  2564.                                             DB(kprintf("looking for 0x%08lx\n",ID));
  2565.  
  2566.                                             for(j = 0 ; j < CurrentPhoneSize ; j++)
  2567.                                             {
  2568.                                                 if(PrivatePhonebook[j]->Header->ID == ID)
  2569.                                                 {
  2570.                                                     DB(kprintf("found it |%s|\n",PrivatePhonebook[j]->Header->Name));
  2571.  
  2572.                                                     if(!GroupNode)
  2573.                                                     {
  2574.                                                         if(!(GroupNode = (PhoneGroupNode *)AllocVecPooled(sizeof(PhoneGroupNode),MEMF_ANY | MEMF_CLEAR)))
  2575.                                                         {
  2576.                                                             Error = ERROR_NO_FREE_STORE;
  2577.  
  2578.                                                             Success = FALSE;
  2579.  
  2580.                                                             break;
  2581.                                                         }
  2582.  
  2583.                                                         strcpy(GroupNode->LocalName,Header.FullName);
  2584.  
  2585.                                                         GroupNode->Node.ln_Name = GroupNode->LocalName;
  2586.  
  2587.                                                         NewList((struct List *)&GroupNode->GroupList);
  2588.  
  2589.                                                         AddTail((struct List *)&LocalPhoneGroupList,(struct Node *)GroupNode);
  2590.                                                     }
  2591.  
  2592.                                                     if(Node = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
  2593.                                                     {
  2594.                                                         PrivatePhonebook[j]->ThisGroup    = GroupNode;
  2595.                                                         PrivatePhonebook[j]->NodeGroup    = Node;
  2596.  
  2597.                                                         Node->VanillaNode.ln_Name    = Node->LocalName;
  2598.                                                         Node->Entry                    = PrivatePhonebook[j];
  2599.  
  2600.                                                         SPrintf(Node->LocalName,"      %s",PrivatePhonebook[j]->Header->Name);
  2601.  
  2602.                                                         AddTail((struct List *)&GroupNode->GroupList,(struct Node *)Node);
  2603.                                                     }
  2604.                                                     else
  2605.                                                     {
  2606.                                                         Error = ERROR_NO_FREE_STORE;
  2607.  
  2608.                                                         Success = FALSE;
  2609.  
  2610.                                                         break;
  2611.                                                     }
  2612.                                                 }
  2613.                                             }
  2614.                                         }
  2615.                                         else
  2616.                                         {
  2617.                                             Error = IoErr();
  2618.  
  2619.                                             Success = FALSE;
  2620.  
  2621.                                             break;
  2622.                                         }
  2623.                                     }
  2624.                                 }
  2625.                                 else
  2626.                                 {
  2627.                                     Error = IoErr();
  2628.  
  2629.                                     Success = FALSE;
  2630.                                 }
  2631.                             }
  2632.  
  2633.                             if(!Success)
  2634.                                 break;
  2635.                         }
  2636.  
  2637.                         if(ConfigChunkType = IsConfigChunk(Chunk->cn_ID))
  2638.                         {
  2639.                             if(!CurrentPhoneSize)
  2640.                                 break;
  2641.  
  2642.                             if(UsePhonePassword)
  2643.                             {
  2644.                                 if(!ReadConfigChunk(Handle,PrivatePhonebook[Index]->Config,ConfigChunkType,Chunk->cn_Size,PasswordBuffer))
  2645.                                 {
  2646.                                     if(Count)
  2647.                                         CurrentPhoneSize = Count - 1;
  2648.                                     else
  2649.                                         CurrentPhoneSize = 0;
  2650.  
  2651.                                     break;
  2652.                                 }
  2653.                                 else
  2654.                                     FixOldConfig(PrivatePhonebook[Index]->Config,ConfigChunkType,TRUE,TermInfo.Version,TermInfo.Revision);
  2655.                             }
  2656.                             else
  2657.                             {
  2658.                                 if(!ReadConfigChunk(Handle,PrivatePhonebook[Index]->Config,ConfigChunkType,Chunk->cn_Size,NULL))
  2659.                                 {
  2660.                                     if(Count)
  2661.                                         CurrentPhoneSize = Count - 1;
  2662.                                     else
  2663.                                         CurrentPhoneSize = 0;
  2664.  
  2665.                                     break;
  2666.                                 }
  2667.                                 else
  2668.                                     FixOldConfig(PrivatePhonebook[Index]->Config,ConfigChunkType,TRUE,TermInfo.Version,TermInfo.Revision);
  2669.                             }
  2670.                         }
  2671.  
  2672.                             // Special treatment for obsolete "FILE" chunk
  2673.  
  2674.                         if(Chunk->cn_ID == ID_FILE)
  2675.                         {
  2676.                             struct Configuration *Config = PrivatePhonebook[Index]->Config;
  2677.                             LONG i;
  2678.  
  2679.                             for(i = PREF_TRANSLATIONFILENAME ; i < PREF_RATES ; i++)
  2680.                             {
  2681.                                 if(!CreateConfigEntry(Config,i))
  2682.                                 {
  2683.                                     Error = ERROR_NO_FREE_STORE;
  2684.                                     break;
  2685.                                 }
  2686.                             }
  2687.  
  2688.                             if(!Error)
  2689.                             {
  2690.                                 strcpy(Config->TranslationFileName,    Config->FileConfig->TranslationFileName);
  2691.                                 strcpy(Config->MacroFileName,        Config->FileConfig->MacroFileName);
  2692.                                 strcpy(Config->CursorFileName,        Config->FileConfig->CursorFileName);
  2693.                                 strcpy(Config->FastMacroFileName,    Config->FileConfig->FastMacroFileName);
  2694.  
  2695.                                 DeleteConfigEntry(Config,PREF_FILE);
  2696.                             }
  2697.                         }
  2698.  
  2699.                         if(Chunk->cn_ID == ID_DATE)
  2700.                         {
  2701.                             if(!PrivatePhonebook[Index]->Header->NoRates)
  2702.                             {
  2703.                                 LONG Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDateOld);
  2704.  
  2705.                                 if(!CurrentPhoneSize)
  2706.                                     break;
  2707.  
  2708.                                 if(TimeDateNode = CreateTimeDateNode(-1,-1,"",Count))
  2709.                                 {
  2710.                                     struct TimeDateOld *Old;
  2711.  
  2712.                                     if(Old = (struct TimeDateOld *)AllocVecPooled(sizeof(struct TimeDateOld) * Count,MEMF_ANY))
  2713.                                     {
  2714.                                         if(ReadChunkBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)) == sizeof(struct TimeDateHeader))
  2715.                                         {
  2716.                                             if(ReadChunkRecords(Handle,Old,sizeof(struct TimeDateOld),Count) == Count)
  2717.                                             {
  2718.                                                 LONG i;
  2719.  
  2720.                                                 for(i = 0 ; i < Count ; i++)
  2721.                                                     ConvertTimeDate(&Old[i],&TimeDateNode->Table[i]);
  2722.  
  2723.                                                 AdaptTimeDateNode(TimeDateNode);
  2724.  
  2725.                                                 AddTail((struct List *)&PrivatePhonebook[Index]->TimeDateList,&TimeDateNode->VanillaNode);
  2726.  
  2727.                                                 LastHadTime = TRUE;
  2728.                                             }
  2729.                                             else
  2730.                                             {
  2731.                                                 Error = IoErr();
  2732.  
  2733.                                                 FreeTimeDateNode(TimeDateNode);
  2734.                                             }
  2735.                                         }
  2736.                                         else
  2737.                                         {
  2738.                                             Error = IoErr();
  2739.  
  2740.                                             FreeTimeDateNode(TimeDateNode);
  2741.                                         }
  2742.  
  2743.                                         FreeVecPooled(Old);
  2744.                                     }
  2745.                                     else
  2746.                                         Error = ERROR_NO_FREE_STORE;
  2747.                                 }
  2748.                                 else
  2749.                                     Error = ERROR_NO_FREE_STORE;
  2750.                             }
  2751.                         }
  2752.  
  2753.                         if(Chunk->cn_ID == ID_DAT2)
  2754.                         {
  2755.                             if(!PrivatePhonebook[Index]->Header->NoRates)
  2756.                             {
  2757.                                 LONG Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDate);
  2758.  
  2759.                                 if(!CurrentPhoneSize)
  2760.                                     break;
  2761.  
  2762.                                 if(TimeDateNode = CreateTimeDateNode(-1,-1,"",Count))
  2763.                                 {
  2764.                                     if(ReadChunkBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)) == sizeof(struct TimeDateHeader))
  2765.                                     {
  2766.                                         if(ReadChunkRecords(Handle,TimeDateNode->Table,sizeof(struct TimeDate),Count) == Count)
  2767.                                         {
  2768.                                             AdaptTimeDateNode(TimeDateNode);
  2769.  
  2770.                                             AddTail((struct List *)&PrivatePhonebook[Index]->TimeDateList,&TimeDateNode->VanillaNode);
  2771.  
  2772.                                             LastHadTime = TRUE;
  2773.                                         }
  2774.                                         else
  2775.                                         {
  2776.                                             Error = IoErr();
  2777.  
  2778.                                             FreeTimeDateNode(TimeDateNode);
  2779.                                         }
  2780.                                     }
  2781.                                     else
  2782.                                     {
  2783.                                         Error = IoErr();
  2784.  
  2785.                                         FreeTimeDateNode(TimeDateNode);
  2786.                                     }
  2787.                                 }
  2788.                                 else
  2789.                                     Error = IoErr();
  2790.                             }
  2791.                         }
  2792.                     }
  2793.  
  2794.                     if(CurrentPhoneSize && !Error)
  2795.                     {
  2796.                         LONG i;
  2797.  
  2798.                         if(!LastHadTime)
  2799.                         {
  2800.                             if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
  2801.                                 AddTail((struct List *)&PrivatePhonebook[Index]->TimeDateList,&TimeDateNode->VanillaNode);
  2802.                         }
  2803.  
  2804.                         DB(for(i = 0 ; i < CurrentPhoneSize ; i++))
  2805.                             DB(kprintf("0x%08lx |%s|\n",PrivatePhonebook[i]->Header->ID,PrivatePhonebook[i]->Header->Name));
  2806.  
  2807.                         if(BookHandle)
  2808.                         {
  2809.                             BookHandle->PhonebookID = PrivatePhonebookID;
  2810.  
  2811.                             if(BookHandle->Phonebook)
  2812.                                 DeletePhonebook(BookHandle->Phonebook,BookHandle->PhoneSize,TRUE);
  2813.  
  2814.                             BookHandle->Phonebook        = PrivatePhonebook;
  2815.                             BookHandle->PhoneSize        = PrivatePhoneSize;
  2816.                             BookHandle->NumPhoneEntries    = CurrentPhoneSize;
  2817.                             BookHandle->DefaultGroup    = Globals.DefaultGroup;
  2818.                             BookHandle->AutoDial        = Globals.AutoDial;
  2819.                             BookHandle->AutoExit        = Globals.AutoExit;
  2820.  
  2821.                             if(BookHandle->PhoneGroupList)
  2822.                             {
  2823.                                 DeletePhoneGroupList(BookHandle->PhoneGroupList);
  2824.  
  2825.                                 MoveList((struct List *)&LocalPhoneGroupList,(struct List *)BookHandle->PhoneGroupList);
  2826.                             }
  2827.                             else
  2828.                                 DeletePhoneGroupList(&LocalPhoneGroupList);
  2829.  
  2830.                             CopyMem(PasswordBuffer,BookHandle->PhonePassword,20);
  2831.                             BookHandle->PhonePasswordUsed = UsePhonePassword;
  2832.  
  2833.                             for(i = BookHandle->NumPhoneEntries ; i < BookHandle->PhoneSize ; i++)
  2834.                             {
  2835.                                 if(BookHandle->Phonebook[i])
  2836.                                 {
  2837.                                     if(BookHandle->Phonebook[i]->Config)
  2838.                                         DeleteConfiguration(BookHandle->Phonebook[i]->Config);
  2839.  
  2840.                                     FreeVecPooled(BookHandle->Phonebook[i]);
  2841.  
  2842.                                     BookHandle->Phonebook[i] = NULL;
  2843.                                 }
  2844.                             }
  2845.  
  2846.                             for(i = 0 ; i < BookHandle->NumPhoneEntries ; i++)
  2847.                             {
  2848.                                 FinalFix(BookHandle->Phonebook[i]->Config,TRUE,TermInfo.Version,TermInfo.Revision);
  2849.                                 StripGlobals(BookHandle->Phonebook[i]->Config);
  2850.                             }
  2851.                         }
  2852.                         else
  2853.                         {
  2854.                             PhonebookID = PrivatePhonebookID;
  2855.  
  2856.                             if(Phonebook)
  2857.                                 DeletePhonebook(Phonebook,PhoneSize,TRUE);
  2858.  
  2859.                             Phonebook                = PrivatePhonebook;
  2860.                             PhoneSize                = PrivatePhoneSize;
  2861.                             NumPhoneEntries            = CurrentPhoneSize;
  2862.                             PhonebookDefaultGroup    = Globals.DefaultGroup;
  2863.                             PhonebookAutoDial        = Globals.AutoDial;
  2864.                             PhonebookAutoExit        = Globals.AutoExit;
  2865.  
  2866.                             DeletePhoneGroupList(&PhoneGroupList);
  2867.  
  2868.                             MoveList((struct List *)&LocalPhoneGroupList,(struct List *)&PhoneGroupList);
  2869.  
  2870.                             CopyMem(PasswordBuffer,PhonePassword,20);
  2871.                             PhonePasswordUsed = UsePhonePassword;
  2872.  
  2873.                             for(i = NumPhoneEntries ; i < PhoneSize ; i++)
  2874.                             {
  2875.                                 if(Phonebook[i])
  2876.                                 {
  2877.                                     if(Phonebook[i]->Config)
  2878.                                         DeleteConfiguration(Phonebook[i]->Config);
  2879.  
  2880.                                     FreeVecPooled(Phonebook[i]);
  2881.  
  2882.                                     Phonebook[i] = NULL;
  2883.                                 }
  2884.                             }
  2885.  
  2886.                             for(i = 0 ; i < NumPhoneEntries ; i++)
  2887.                             {
  2888.                                 FinalFix(Phonebook[i]->Config,TRUE,TermInfo.Version,TermInfo.Revision);
  2889.                                 StripGlobals(Phonebook[i]->Config);
  2890.                             }
  2891.                         }
  2892.  
  2893.                         FreeDialList(TRUE);
  2894.  
  2895.                         Success = TRUE;
  2896.                     }
  2897.                     else
  2898.                     {
  2899.                         DeletePhoneGroupList(&LocalPhoneGroupList);
  2900.  
  2901.                         if(PrivatePhoneSize)
  2902.                         {
  2903.                             DeletePhonebook(PrivatePhonebook,PrivatePhoneSize,TRUE);
  2904.  
  2905.                             Success = FALSE;
  2906.                         }
  2907.                     }
  2908.                 }
  2909.  
  2910.                 CloseIFF(Handle);
  2911.             }
  2912.  
  2913.             Close(Handle->iff_Stream);
  2914.         }
  2915.         else
  2916.             Error = IoErr();
  2917.  
  2918.         FreeIFF(Handle);
  2919.     }
  2920.     else
  2921.         Error = ERR_NO_MEM;
  2922.  
  2923.     if(Error)
  2924.         SetIoErr(Error);
  2925.  
  2926.     if(UseOld)
  2927.         return(LoadOldPhonebook(Name,BookHandle));
  2928.     else
  2929.         return(Success);
  2930. }
  2931.  
  2932.     /* WriteConfig(STRPTR Name,struct Configuration *Config):
  2933.      *
  2934.      *    Write the configuration to a file, very much like
  2935.      *    WriteIFFData().
  2936.      */
  2937.  
  2938. BOOL
  2939. WriteConfig(STRPTR Name,struct Configuration *Config)
  2940. {
  2941.     struct IFFHandle    *Handle;
  2942.     BOOL                 Success = FALSE;
  2943.     LONG                 Error;
  2944.  
  2945. #ifdef BETA
  2946.     if(ShowRequest(Window,
  2947.         "ONE WAY TICKET WARNING!\n\n"
  2948.         "The file format written by this `term' beta test release\n"
  2949.         "cannot be read by older program releases. And just as it\n"
  2950.         "happens, not even the author of these lines can guarantee\n"
  2951.         "you that this very program will be able to read the files\n"
  2952.         "back it writes.",
  2953.     "Uh oh...|I know what I'm doing"))
  2954.         return(TRUE);
  2955. #endif
  2956.  
  2957.         /* Allocate a handle. */
  2958.  
  2959.     if(Handle = AllocIFF())
  2960.     {
  2961.             /* Open an output stream. */
  2962.  
  2963.         if(Handle->iff_Stream = Open(Name,MODE_NEWFILE))
  2964.         {
  2965.                 /* Tell iffparse that this is
  2966.                  * a DOS handle.
  2967.                  */
  2968.  
  2969.             InitIFFasDOS(Handle);
  2970.  
  2971.                 /* Open the handle for writing. */
  2972.  
  2973.             if(!(Error = OpenIFF(Handle,IFFF_WRITE)))
  2974.             {
  2975.                     /* Push outmost chunk onto stack. */
  2976.  
  2977.                 if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  2978.                 {
  2979.                         /* Add a version identifier. */
  2980.  
  2981.                     if(!(Error = PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN)))
  2982.                     {
  2983.                         struct TermInfo TermInfo;
  2984.  
  2985.                         TermInfo.Version    = CONFIG_FILE_VERSION;
  2986.                         TermInfo.Revision    = CONFIG_FILE_REVISION;
  2987.  
  2988.                             /* Update the other configuration pointer as well. */
  2989.  
  2990.                         Config->SerialConfig->LastVersionSaved    = TermVersion;
  2991.                         Config->SerialConfig->LastRevisionSaved    = TermRevision;
  2992.  
  2993.                             /* Write the version data. */
  2994.  
  2995.                         if(WriteChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  2996.                         {
  2997.                                 /* Pop the version chunk, i.e. write it to the file. */
  2998.  
  2999.                             if(Error = PopChunk(Handle))
  3000.                                 Success = FALSE;
  3001.                             else
  3002.                             {
  3003.                                 if(WriteConfigChunks(Handle,Config,NULL,NULL))
  3004.                                 {
  3005.                                     LONG i;
  3006.  
  3007.                                     Success = TRUE;
  3008.  
  3009.                                     for(i = 0 ; Success && i < WINDOW_COUNT ; i++)
  3010.                                     {
  3011.                                         if(!(Error = PushChunk(Handle,0,ID_WINF,sizeof(struct WindowInfo))))
  3012.                                         {
  3013.                                             if(WriteChunkBytes(Handle,&WindowInfoTable[i],sizeof(struct WindowInfo)) == sizeof(struct WindowInfo))
  3014.                                             {
  3015.                                                 if(Error = PopChunk(Handle))
  3016.                                                     Success = FALSE;
  3017.                                             }
  3018.                                             else
  3019.                                             {
  3020.                                                 Error = IoErr();
  3021.  
  3022.                                                 Success = FALSE;
  3023.                                             }
  3024.                                         }
  3025.                                         else
  3026.                                             Success = FALSE;
  3027.                                     }
  3028.                                 }
  3029.                             }
  3030.                         }
  3031.                         else
  3032.                         {
  3033.                             Error = IoErr();
  3034.  
  3035.                             Success = FALSE;
  3036.                         }
  3037.                     }
  3038.  
  3039.                         /* Seems that we're done, now try to pop the FORM chunk
  3040.                          * and return.
  3041.                          */
  3042.  
  3043.                     if(Success)
  3044.                     {
  3045.                         if(Error = PopChunk(Handle))
  3046.                             Success = FALSE;
  3047.                     }
  3048.                 }
  3049.  
  3050.                     /* Close the handle (flush any pending data). */
  3051.  
  3052.                 CloseIFF(Handle);
  3053.             }
  3054.  
  3055.                 /* Close the DOS handle itself. */
  3056.  
  3057.             Close(Handle->iff_Stream);
  3058.         }
  3059.         else
  3060.             Error = IoErr();
  3061.  
  3062.             /* And free the IFF handle. */
  3063.  
  3064.         FreeIFF(Handle);
  3065.     }
  3066.     else
  3067.         Error = ERR_NO_MEM;
  3068.  
  3069.     if(Success)
  3070.         AddProtection(Name,FIBF_EXECUTE);
  3071.     else
  3072.         SetIoErr(Error);
  3073.  
  3074.     return(Success);
  3075. }
  3076.  
  3077.     /* ReadConfig(STRPTR Name,struct Configuration *Config):
  3078.      *
  3079.      *    Read the configuration file, very much the same as ReadIFFData().
  3080.      */
  3081.  
  3082. BOOL
  3083. ReadConfig(STRPTR Name,struct Configuration *Config)
  3084. {
  3085.     struct IFFHandle    *Handle;
  3086.     BOOL                 Success    = FALSE,
  3087.                          UseOld        = FALSE;
  3088.     struct ContextNode    *Chunk;
  3089.     LONG                 ConfigChunkType;
  3090.     LONG                 Error = 0;
  3091.  
  3092.     if(Handle = AllocIFF())
  3093.     {
  3094.         if(Handle->iff_Stream = Open(Name,MODE_OLDFILE))
  3095.         {
  3096.             InitIFFasDOS(Handle);
  3097.  
  3098.             if(!(Error = OpenIFF(Handle,IFFF_READ)))
  3099.             {
  3100.                 if(!StopChunks(Handle,Stops,NUM_STOPS))
  3101.                 {
  3102.                     struct TermInfo TermInfo;
  3103.  
  3104.                     while(!ParseIFF(Handle,IFFPARSE_SCAN))
  3105.                     {
  3106.                         Chunk = CurrentChunk(Handle);
  3107.  
  3108.                             /* Oops! Someone is trying to
  3109.                              * use the phone book file as
  3110.                              * a configuration file.
  3111.                              */
  3112.  
  3113.                         if(Chunk->cn_ID == ID_CAT)
  3114.                         {
  3115.                             Success = FALSE;
  3116.  
  3117.                             break;
  3118.                         }
  3119.  
  3120.                         if(Chunk->cn_ID == ID_VERS)
  3121.                         {
  3122.                             if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  3123.                             {
  3124.                                 if(TermInfo.Version != CONFIG_FILE_VERSION || (TermInfo.Version == CONFIG_FILE_VERSION && TermInfo.Revision > CONFIG_FILE_REVISION))
  3125.                                 {
  3126.                                     if(TermInfo.Version == 2 && TermInfo.Revision == 4)
  3127.                                         UseOld = TRUE;
  3128.  
  3129.                                     if(TermInfo.Version != 3)
  3130.                                         break;
  3131.                                 }
  3132.                             }
  3133.                             else
  3134.                             {
  3135.                                 Error = IoErr();
  3136.  
  3137.                                 break;
  3138.                             }
  3139.                         }
  3140.  
  3141.                         if(Chunk->cn_ID == ID_WINF)
  3142.                         {
  3143.                             struct WindowInfo Info;
  3144.  
  3145.                             if(ReadChunkBytes(Handle,&Info,sizeof(Info)) == sizeof(Info))
  3146.                             {
  3147.                                 Success = TRUE;
  3148.  
  3149.                                 ReplaceWindowInfo(&Info);
  3150.                             }
  3151.                             else
  3152.                             {
  3153.                                 Error = IoErr();
  3154.  
  3155.                                 Success = FALSE;
  3156.                                 break;
  3157.                             }
  3158.                         }
  3159.                         else
  3160.                         {
  3161.                             if(ConfigChunkType = IsConfigChunk(Chunk->cn_ID))
  3162.                             {
  3163.                                 if(ReadConfigChunk(Handle,Config,ConfigChunkType,Chunk->cn_Size,NULL))
  3164.                                 {
  3165.                                     FixOldConfig(Config,ConfigChunkType,FALSE,TermInfo.Version,TermInfo.Revision);
  3166.  
  3167.                                     Success = TRUE;
  3168.                                 }
  3169.                                 else
  3170.                                 {
  3171.                                     Error = IoErr();
  3172.  
  3173.                                     Success = FALSE;
  3174.  
  3175.                                     break;
  3176.                                 }
  3177.                             }
  3178.  
  3179.                                 // Special treatment for obsolete "FILE" chunk
  3180.  
  3181.                             if(Chunk->cn_ID == ID_FILE)
  3182.                             {
  3183.                                 struct Configuration *LocalConfig = Config;
  3184.                                 LONG Type;
  3185.  
  3186.                                 for(Type = PREF_TRANSLATIONFILENAME ; Type < PREF_RATES ; Type++)
  3187.                                 {
  3188.                                     if(!CreateConfigEntry(LocalConfig,Type))
  3189.                                     {
  3190.                                         Error = ERROR_NO_FREE_STORE;
  3191.  
  3192.                                         Success = FALSE;
  3193.  
  3194.                                         break;
  3195.                                     }
  3196.                                 }
  3197.  
  3198.                                 if(!Error)
  3199.                                 {
  3200.                                     strcpy(LocalConfig->TranslationFileName,    LocalConfig->FileConfig->TranslationFileName);
  3201.                                     strcpy(LocalConfig->MacroFileName,            LocalConfig->FileConfig->MacroFileName);
  3202.                                     strcpy(LocalConfig->CursorFileName,            LocalConfig->FileConfig->CursorFileName);
  3203.                                     strcpy(LocalConfig->FastMacroFileName,        LocalConfig->FileConfig->FastMacroFileName);
  3204.  
  3205.                                     DeleteConfigEntry(LocalConfig,PREF_FILE);
  3206.                                 }
  3207.                             }
  3208.                         }
  3209.                     }
  3210.  
  3211.                     if(Success)
  3212.                         FinalFix(Config,FALSE,TermInfo.Version,TermInfo.Revision);
  3213.                 }
  3214.  
  3215.                 CloseIFF(Handle);
  3216.             }
  3217.  
  3218.             Close(Handle->iff_Stream);
  3219.         }
  3220.  
  3221.         FreeIFF(Handle);
  3222.     }
  3223.     else
  3224.         Error = IoErr();
  3225.  
  3226.     if(Error)
  3227.         SetIoErr(Error);
  3228.  
  3229.     if(UseOld)
  3230.         return(ReadOldConfig(Name,Config));
  3231.     else
  3232.         return(Success);
  3233. }
  3234.